home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / pcutils / windows / genesis / doc / progdoc.txt < prev   
Text File  |  1995-12-30  |  166KB  |  5,088 lines

  1.  
  2. 16
  3.   
  4.             Genesis Programming Specification
  5.  
  6. Author:                              Steven Woodman
  7. Date:                                10/7/95
  8. Revision:                            5
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.           (C) Silicon Dream Ltd. 1995
  25.  
  26. TABLE OF CONTENTS
  27.  
  28. GEOMETRY SPECIFICATION                                  5
  29. INTRODUCTION                                            5
  30.  PROVIDING A NEW GEOMETRY ENGINE                       6
  31.  WRITING NEW TOOLS                                     6
  32.  USING GEOMETRY FOR APPLICATIONS                       7
  33. HOW THE GEOMETRY API WORKS                              7
  34.  VERTICIES                                             7
  35.  PATCHES                                               8
  36.   HOW DO YOU SPECIFY WHICH SIDE IS WHICH               8
  37.   PENETRATING PATCHES                                  8
  38.  NORMALS                                               9
  39.  OBJECTS                                               9
  40.  LIGHTS                                               10
  41.   AMBIENT LIGHT                                       10
  42.  COORDINATE SYSTEMS                                   10
  43.   HOW DO WE DEFINE THE POSITION OF A COORDINATE SYSTEM11
  44.   MATRICIES                                           11
  45.   COORDINATE SYSTEM `HANDEDNESS'                      11
  46.  SURFACE TYPES                                        12
  47.   TEXTURES                                            12
  48.     TILED TEXTURES                                    13
  49.     RECURSIVE TEXTURES                                13
  50.     BUMP MAPPING                                      13
  51.     TEXTURE ORIENTATION AND SIZE                      13
  52.     NON-LINEAR TEXTURE PROJECTIONS                    13
  53.   SPECULAR HIGHLIGHTS                                 14
  54.   TRANSPARENT SURFACES                                14
  55. USING THE API                                          14
  56. GEOMETRY API REFERENCE                                 15
  57.  USE OF C++ MATHS CLASSES                             15
  58.  GLOBAL FUNCTIONS                                     16
  59.  COORDINATE SYSTEM FUNCTIONS                          21
  60.  OBJECT CONSTRUCTION FUNCTIONS                        25
  61.  LIGHTING FUNCTIONS                                   34
  62.  LOADING AND SAVING                                   36
  63.  STRUCTURES AND TYPES                                 38
  64. TOOL INTERFACE                                         46
  65. INTRODUCTION                                           46
  66. WRITING CUSTOM TOOLS                                   47
  67.  THE TOOL OBJECT                                      47
  68.  THE TOOL'S CONFIGURATION DIALOG BOX                  47
  69. HOW TO TELL THE EDITOR ABOUT YOUR TOOL                 48
  70. OVERRIDING TOOL FUNCTIONS                              48
  71. CALLING SEQUENCE                                       48
  72.  MODIFYING AND UNDOING                                49
  73.  DRAWING INTO THE VIEW                                49
  74.   DRAWING RETURN CODES                                49
  75.     REDRAW_ALL                                        49
  76.     REDRAW_NONE                                       50
  77.     REDRAW_OBJECT_WIRE                                50
  78.     REDRAW_TOOL                                       50
  79.     REDRAW_NOTOOL                                     50
  80.     REDRAW_REFRESH                                    50
  81.   GETTING 2D SCREEN COORDINATES                       50
  82. DRAGGING WITH THE MOUSE                                51
  83.  XOR'ING IN MULTIPLE VIEWS                            51
  84.   DRAWSOFAR PARAMETERS                                52
  85. GENERAL GUIDELINES                                     52
  86.  HELP ON USING TOOLS                                  52
  87.  DISPLAYING TEXT STRINGS                              52
  88.  COORDINATE SYSTEM TYPES                              52
  89. A NOTE FOR C USERS                                     53
  90. OVERRIDABLES                                           54
  91. SUPPORT                                                58
  92. QUICK START TO WRITING TOOLS                           69
  93. MATHS LIBRARY                                          71
  94. FOR C USERS                                            71
  95. FOR C++ USERS                                          71
  96.  VECTORS                                              72
  97.  LONG VECTORS                                         73
  98.  POLAR VECTORS                                        73
  99.  MATRICIES                                            74
  100. DEBUG LIBRARY                                          75
  101. INSTANCES OF DEBUG LIBRARY                             76
  102. WRITING A GEOMETRY ENGINE                              77
  103. ERRORS                                                 77
  104. HANDLES                                                77
  105. UNSUPPORTED FEATURES                                   78
  106. HELPER LIBRARY                                         78
  107. API'S                                                  78
  108. GEOMETRY SPECIFICATION
  109.  
  110. Introduction
  111.  
  112. This document describes the Geometry API. It assumes an
  113. understanding of programming in C++ and a basic knowledge
  114. of programming in Windows. Knowledge of mathmatics is not
  115. a prerequisite although an understanding of vectors and
  116. matricies is helpful.
  117.  
  118. Figure 1 shows the various component parts of the Genesis
  119. package and how they relate to one another.
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140. Figure 1. Components of Genesis
  141.  
  142. Geometry is the part of Genesis that actually stores the
  143. data structures representing the 3D models and performs
  144. all the difficult 3D rendering. The editor makes various
  145. calls to the Geometry API as the user performs various
  146. actions on the program. For instance when the user
  147. presses the `Pos' button on the control bar the editor
  148. makes a call to the SetCamera routine in order to
  149. position the camera ready for rendering. When the user
  150. selects the `Render' menu item, a call to Render is made.
  151. A user will never need to know these details, however
  152. there are three scenerios in which a programmer might
  153. want to understand how the API works.
  154.  
  155.      ·    Providing a new Geometry engine
  156. ·    Writing new tools for the editor
  157. ·    Using Geometry for applications
  158.  
  159. Whichever scnerio you are interested in the maths and
  160. debug libraries supplied in this package will prove
  161. invalueable programming aids (See the `Maths Library' and
  162. `Debug Library' sections).
  163.  
  164.  
  165.  
  166. Providing a new Geometry engine
  167.  
  168. The default Geometry engine is a single DLL which
  169. provides software for 3D graphics processing. It doesn't
  170. support accelerated hardware because at the time of
  171. writing we couldn't possibly anticipate what manner of 3D
  172. acceleration hardware might become available in the
  173. future. When third parties release their new 3D
  174. processing  systems, wether hardware or software based,
  175. Genesis can support them simply by writing a DLL to
  176. interface the Geometry API to the new hardware/software.
  177. Imagine for example that the XYZ computer company came
  178. out with a board and a software interface that gave PC's
  179. the ability to render at over a million polygons a
  180. second, then with a few days work Genesis with all its
  181. powerfull editing tools could be rendering much faster
  182. and completely transparently from the users viewpoint.
  183.  
  184. To create a new Geometry engine you will create a DLL
  185. implementing the Geometry API but which maps those
  186. functions onto the software functions provided by the
  187. third party 3D comapny. A set of routines is supplied in
  188. this package to make this job easier (See the `Geometry
  189. Helper Library' section).
  190.  
  191. Writing new tools
  192.  
  193. Genesis is very powerfull in the respect that if a
  194. function is needed which isn't available, with a little
  195. programming knowledge you can create your own extensions
  196. thereby tailoring Genesis to your own particular set of
  197. problems. For instance, an architect might spend most of
  198. his time creating doors, all of which are different but
  199. all share basic characterisitics. By writing a door
  200. creation tool, he can position the cursor where he wants
  201. the door, press a button in the tool box representing his
  202. custom tool, enter a few basic parameters into a dialog
  203. box, and hey presto, a door appears. In this way users
  204. can build their own libraries of tools all of which are
  205. seemlessly integrated into the program. In this way
  206. Genesis can be considered as little more than a shell
  207. designed to support a vast variety of `plug in' tools to
  208. cover every concievable problem in 3D design.
  209.  
  210. To create a new tool you will create a DLL implementing a
  211. C++ class derived from a class that we supply (See the
  212. `Writing Tools' section). Dont worry if you are not
  213. familiar with C++ as we provide a C++ template source
  214. file. All you need to do is to fill in the relevent
  215. functions using C. You will use the Geometry API plus
  216. functions in the base class to implement the
  217. functionality of the tool. Minimal knowledge of
  218. programming in Windows is required.
  219.  
  220. Some of the more general tools we thought might be
  221. usefull are listed below. Basically anything which
  222. manipulates 3D models can be implemented as a tool.
  223. However there are in fact an unlimited number considering
  224. the huge range of applications Genesis might be applied
  225. to:
  226.  
  227. 1.   Primitive creation types (Creates primitive objects)
  228.      ·    Patches
  229.      ·    Spheres/Semi spheres
  230. ·    Cylinders
  231. ·    Boxes
  232. ·    Cones
  233. ·    Torus's
  234. ·    Ellipsoids/General curved area creators
  235. 2.   Tradional types (Often found on more conventional
  236.  modellers)
  237.      ·    Lathe (Spins a 2D outline into a 3D shape)
  238.      ·    Extrude (Expands a 2D outline to give it 3D depth)
  239. ·    Copy (Makes a copy of an object)
  240.     ·    Text input window (Calls other tools when you type
  241.       in commands like `sphere rad=10;')
  242. 3.   Savers/Loaders (for various file formats)
  243.      ·    3DS
  244.      ·    DXF
  245. ·    WAD (Doom game file format)
  246. 4.   CSG tools (Enables new objects to be created by
  247.  combining existing ones)
  248.      ·    Union operator (joins two objects as one object;
  249.       a=b|c)
  250.      ·    Intersection operator (creates one object from the
  251.       overlapping volume of two others; a=b&c)
  252.      ·    Subtraction operator (subtracts one object from
  253.       another; a=b-c)
  254.      ·    Exclusive OR operator (creates an object as the
  255.       volume of two other objects excluding any intersection;
  256.       a=b^c)
  257. 5.   Imaginitive ideas
  258.      ·    Fractal landscape generator
  259.     ·    `Physical law' animation tools
  260.  
  261. Using Geometry for applications
  262.  
  263. The Geometry engine can be used via its API to construct
  264. new applications totally separate from the Genesis
  265. editor. For instance; Flight simulators, medical imaging
  266. applications, oil field data visualisation, 3D games to
  267. mention but a few. The advantages of using the Geometry
  268. API are twofold. Firstly all the difficult 3D stuff is
  269. already taken care of as well as a lot of other usefull
  270. bits such as routines to manipulate 3D vectors and
  271. matricies etc. (See `Maths Library' section). Secondly,
  272. any new hardware appearing for which a geometry engine is
  273. written (see above) will automatically work with the new
  274. application. So your flight simulator might not look too
  275. quick on a 386 PC but when XYZ's new 3D processor board
  276. hits the market suddenly without any additional
  277. programming effort your 386 looks like a million dollar
  278. professional simulator.
  279.  
  280. To write a new application the Geometry DLL is used as a
  281. stand alone DLL, just like any other, which is called
  282. from your application according to the Geometry API.
  283.  
  284. How the Geometry API works
  285.  
  286. The Geometry design is a heirarchical one. Objects such
  287. as verticies, patches and normals belong to objects.
  288. Objects belong to coordinate systems as do lights.
  289. Coordinate systems belong to other coordinates system.
  290. Coordinate system along with all their associated objects
  291. can be rendered. The following sections decribe the
  292. terminology further.
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305. Figure 2. Construction of a cube
  306.  
  307. Verticies
  308.  
  309. A vertex is a point in 3D space described by an x, y and
  310. a z value. A cube has 6 verticies or corners, 12 edges,
  311. and 8 faces.
  312.  
  313. Patches
  314.  
  315. A patch is a polygon or face defined by 3 or more
  316. verticies, such as the 8 faces of the cube. You build up
  317. 3D models by connecting patches together exactly like a
  318. patchwork quilt. A patch has a surface type indicator
  319. defining its colour, texture and reflection
  320. characteristics. Patches are always flat but can be made
  321. to appear curved by associating normals with each of its
  322. verticies (see below). Because they are always flat care
  323. should be taken when creating patches of more than 4
  324. verticies that all the verticies lie on a plane otherwise
  325. Geometry will politely inform you of your error.
  326.  
  327. Patches are one sided entities meaning they are intended
  328. to be viewed only from one side. An attempt to view it
  329. from the other side will in fact make it invisible. This
  330. might sound strange but is actually quite logical. For
  331. instance as you look around your cube you are always
  332. seeing the individual patches from the same side, to view
  333. them from the other side you will need to go inside the
  334. cube. If you did this you would actually see straight
  335. through to the outside because the patches would be
  336. invisible. What you need to do is design the inside of
  337. the cube to prevent you seeing out, ie.  you need 8 more
  338. patches inside facing the other way. The reason for this
  339. is that it makes rendering quite a bit faster. In cases
  340. where you dont want to go inside the cube you only need 8
  341. single sided patches which render much quicker than 8
  342. double sided ones. This is a technique used by almost all
  343. real time rendering systems.
  344.  
  345. How do you specify which side is which
  346.  
  347. Geometry adopts the convention that all patches must have
  348. their verticies ordered clockwise when viewed from the
  349. correct side. It is the ordering of the verticies which
  350. defines which side is the solid looking side.  When
  351. creating patches you must think about this, if you order
  352. them wrongly your object will be visible from the inside,
  353. and probably completely invisible from outside.
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367. Figure 3. Penetrating patches
  368.  
  369. Penetrating patches
  370.  
  371. Care should be taken when constructing objects that one
  372. patch should not penetrate another as not all Geometry
  373. engines support penetrating surfaces, and in fact the
  374. default Geometry engine doesn't. If you want an object to
  375. look like it has been pierced with another the patches
  376. should be designed to give this effect without actually
  377. penetrating. The editor's CSG union tool will allow users
  378. to do this.
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395. Figure 4. Normals
  396.  
  397. Normals
  398.  
  399. A normal is a direction specified in 3D by an x, y and z
  400. value, rather like a vertex. Normals are used to make
  401. objects appear curved. By associating a normal with each
  402. corner of our cube, we are telling the renderer that when
  403. it is working out the light shading on those points, to
  404. assume that the gradient of the surface at that point is
  405. such the normal's direction sticks out at 90 degrees to
  406. it. In fact this isn't so, as we might have 3 or more
  407. patches converging at a vertex (as in the cube example),
  408. but thanks to the normal the shading is generated as if
  409. it were a single face at that point. If we tell Geometry
  410. that an object we are constructing is to appear curved
  411. the `autosmooth' feature can generate the normal
  412. information automatically for us. There are some instance
  413. however when we would like to create them explicitly.
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426. Figure 5. Missing or wrongly ordered patches
  427.  
  428. Objects
  429.  
  430. An object is a 3D model constructed out of patches. Since
  431. patches are single sided it should be fully enclosed by
  432. patches so that we cannot see the inside of any patch
  433. from any angle. As mentioned above you would in fact not
  434. see it at all giving the appearance of a hole in your
  435. object. Another way to think  about it is that each edge
  436. of every patch should have another patch connected to it.
  437. Geometry will not complain if you attempt to render an
  438. incomplete object but the results can look confusing seen
  439. from some angles.
  440.  
  441. The editor's `Enclosed' tool will highlight any
  442. unconnected edges.
  443.  
  444.  
  445.  
  446. Lights
  447.  
  448. As well as a 3D position, lights can have characteristics
  449. such as intensity, colour and direction although the
  450. default Geometry engine actually only takes notice of the
  451. position and intensity.
  452.  
  453. Ambient Light
  454.  
  455. Real life lighting very rarely leaves you completly in
  456. the dark. This is because there is always light coming
  457. from somewhere, eg. sunlight, moonlight, a far off screet
  458. lamp etc. In 3D modeller environments we find it
  459. difficult to account for all these things, so to ensure
  460. that at least a little bit of light falls even on
  461. surfaces where no light sources can reach, we use ambient
  462. light. The ambient light setting is simply an intensity
  463. value added to those generated by the light sources when
  464. rendering a scene.
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481. Figure 6. A coordinate system heirarchy
  482.  
  483. Coordinate systems
  484.  
  485. Every 3D coordinate you specify for lights, verticies,
  486. normals and therefore patches and objects is relative to
  487. an origin, ie. point 0, 0, 0. The position of the origin
  488. relative to whatever other stuff might get rendered is
  489. defined by the coordinate system. A coordinate system and
  490. all its associated objects and lights etc. can be moved
  491. quickly and easily relative to everything else simply by
  492. moving the coordinate system. The coordinate system moves
  493. and everything in it moves. As an example, imagine a huge
  494. landscape. This would be defined in the top level
  495. coordinate system by loads of patches. In this landscape
  496. there is a river, and on the river a large boat
  497. containing lots of people. We want to animate this boat
  498. moving down the river. As the boat moves twisting and
  499. turning as it goes, so do all the people.
  500. When creating the animation we have to define the
  501. position of the boat at each frame, but we shouldn't also
  502. have to define the position of every individual person.
  503. We do this by creating a coordinate system as a child of
  504. the landscape's coordinate system. and make the boat and
  505. everying in it belong it. We then only have to move the
  506. coordinate system.
  507.  
  508. Coordinate systems are also usefull even if we're not
  509. making animations as it provides us with a new origin and
  510. axis to work with when designing objects at awkward
  511. angles to the x, y and z axis's in the parent coordinate
  512. system.
  513.  
  514.  
  515.  
  516. How do we define the position of a coordinate system
  517.  
  518. This brings us to the most difficult mathmatical concept
  519. used in Geometry. The straight answer is; a 4x4 matrix.
  520. Some of you will know what I mean, some will require a
  521. further explanation.
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532. Figure 7. Matricies
  533.  
  534. Matricies
  535.  
  536. A matrix is a set of numbers laid out in a rectangle.
  537. Matricies can have any number of columns by any number of
  538. rows. The matricies we're concerned with in Geometry are
  539. all 4x4. When defining the position of a new coordinate
  540. system its not just a matter of specifying the 3D
  541. coordinates of a new origin because we also have to
  542. define the `orientation' of the new axis. The
  543. `orientation' means the angle of the new x, y and z axis
  544. relative to the parent coordinate system. The x axis
  545. isn't neccessarily parallel to the parents x axis it
  546. could be rotated a bit in the y axis and bit in the z
  547. axis and even enlarged or shrunk relative to the parent.
  548. Matricies we're designed to represent this type of
  549. information. Thankfully the maths library supplies a C++
  550. class and C functions that make working with matricies
  551. easy.
  552.  
  553.  
  554.  
  555.  
  556.  
  557. Figure 8. Coordinate system `handedness'
  558.  
  559. Coordinate system `handedness'
  560.  
  561. Two types of coordinate system can be defined; left and
  562. right handed. It is neccessary to tell Geometry which
  563. type you have defined otherwise the clockwise ordering of
  564. verticies in a patch is meaningless. To find out which
  565. type you want, position your right hand so that you index
  566. finger and second finger are at right angles to each
  567. other and your thumb is pointing up. In a right handed
  568. coordinate system if the x axis has the direction of the
  569. index finger and the y the direction of the second finger
  570. then the z axis will have the direction of the thumb. The
  571. same applies to a left handed coordinate system if you
  572. use your left hand.
  573.  
  574. Coordinate systems and all their associated objects can
  575. be moved within the coordinate system heirarchy. For
  576. instance, coordinate system A has a child; B, and B has a
  577. child; C. C can then be moved so that it becomes a child
  578. of A, meaning it is now a sibling of B. This can only be
  579. done only if the coordinate systems are of the same type
  580. otherwise the ordering of the verticies in its patches
  581. effectively get reversed. If you want A to be left handed
  582. and B to be righthanded all you need do is construct a
  583. matrix which reverses one of the axis, either x, y or z.
  584. Functions in the maths library make this easy.
  585.  
  586. The HCSYS_TOP coordinate system is left handed. Unless
  587. you specifically construct a matrix which reverses one of
  588. the axis's of a top level coordinate system, it too will
  589. be left handed.
  590.  
  591. When constructing your data you must bear in mind the
  592. coordinate system it belongs too. If for example you
  593. designed a model of the earth for a right handed
  594. coordinate system but displayed it in a left handed
  595. system then America would end up on the right and Europe
  596. and Asia on the left. No amount of rotating or moving the
  597. object would correct this problem. If something like this
  598. happens to you then look closely at which type of
  599. coordinate system you should be using for you data.
  600.  
  601. Surface Types
  602.  
  603. All patches have a surface type. A surface type not only
  604. describes the colour of the surface but its texture and
  605. how how highlights appear on the surface. The surface
  606. type does not say wether a patch is curved. This is as
  607. attribute of the patch itself.
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626. Figure 9. Tiled textures
  627.  
  628. Textures
  629.  
  630. Texturing is a way of making your object look more
  631. detailed and realistic by projecting an image onto it.
  632. For instance, if you have a wall you can use a brick
  633. texture or a wood grain. The way to image a texture is to
  634. think of an invisible image positioned somewhere in your
  635. scene. Although you cannot see the image directly, the
  636. plane of the image is projected infinitely through the
  637. scene in both directions and the image `rubs off' on any
  638. patch which uses the surface type of this texture. Think
  639. of it a bit like a film projector that shines on anything
  640. placed in fron of it. The only difference is the film
  641. projector image gets bigger the further in front the
  642. object or screen is moved. Also with a film projector
  643. everything in front gets projected onto, not just
  644. selected patches.
  645.  
  646.  
  647. Tiled textures
  648.  
  649. If you have a huge wall you want to texture and you have
  650. a small image of part of a brick wall to use as the
  651. texture you have a problem. To make the bitmap fit the
  652. wall you have to scale it up. This is quite easily done
  653. but now you have a huge wall made of a few huge bricks!
  654. What you need to do is make the texture `tiled'. Genesis
  655. can place multiple copies of the image alongside each
  656. other and above and below, like tiling an infinitely
  657. large bathroon wall, so that every point in space will be
  658. within `range' of the texture.
  659.  
  660. If you want to use tiled textures you should ensure that
  661. the image you use is `tileable', in other words, if you
  662. place multiple copies alongside each other will you see
  663. the joins. If you can your wall will look like you've
  664. simly pasted up posters of bricks rather than used the
  665. real thing.
  666.  
  667. If you choose not to tile your texture and you have a
  668. patch using the surface type which is not in range of the
  669. texture, then this patch is coloured using the basic
  670. surface colour of the surface type.
  671.  
  672.  
  673. Recursive textures
  674.  
  675. A recursive texture is where each pixel value in your
  676. image refers not to a  colour in the palette of the
  677. image, but rather to another Genesis surface type. This
  678. means you could define a surface type which appears to
  679. have brick on top and through the holes in the brick you
  680. can see wooden slats. You can even define pixel values to
  681. represent real holes in your object that show through to
  682. objects behind. The default Genesis Geometry engine does
  683. not support recursive textures.
  684.  
  685.  
  686. Bump mapping
  687.  
  688. With bump mapping the pixel values in the image refer to
  689. the height of a bump which is to appear at that point on
  690. any patch its projected onto. Obviously no real physical
  691. bump appears on the object, but the shading at the point
  692. is modified to make the surface appear irregular at that
  693. point. The effect is extremely convincing as long as you
  694. dont get too close to the object. The default Geometry
  695. engine does not support bump mapping.
  696.  
  697.  
  698. Texture orientation and size
  699.  
  700. Having discussed how textures work, we still haven't
  701. addressed the question of how we specify the orientation
  702. of the texture. Its quite simple really, as before we use
  703. a 4x4 matrix to define the orientation relative to the
  704. origin of a coordinate system. If you use an identity
  705. matrix (this is really a null matrix, one that does
  706. nothing) then your texture will be aligned with the x and
  707. y axis of the coordinate system and will project through
  708. the z. The size will be such that if your image is 100
  709. pixels wide by 80 high then it will extend from the
  710. origin to x=100, and y=80. Any other matrix can be used
  711. to position, rotate, and scale the image away from the
  712. origin.
  713.  
  714.  
  715. Non-linear texture projections
  716.  
  717. Texture matricies can also be used to define non-linear
  718. projections. For instance, suppose you want to project
  719. bricks onto a sphere. With a normal linear projection as
  720. described above, your bricks will distort as they go
  721. around the sides of the sphere, like putting a football
  722. in front of a film projector. The way around this is to
  723. use a spherical mapping. In other words create a matrix
  724. to map points on a sphere onto a flat image. Cylindrical,
  725. conic and even toriodal projections might come in handy
  726. for other types of objects.
  727.  
  728.  
  729. Specular highlights
  730.  
  731. Specular reflections are what you see when you take a
  732. shiny surface such as a metal tray, and angle it towards
  733. a light. You will often see brightly lit areas where the
  734. light bounces off the object towards your eye. The exact
  735. shape, size and brightness of these highlights depends on
  736. what the surface is made of. Since the default Geometry
  737. engine (or any using Gouraud as opposed to Phong shading)
  738. performs its lighting calculations at each vertex only,
  739. the more verticies you have the more accurately the
  740. lighting will mimic the surface type. Even if you have a
  741. flat square surface, to get the most visually accurate
  742. highlights the surface should be made of lots of small
  743. flat patches rather than one large one.
  744.  
  745. In technical terms the specular reflection
  746. characteristics relates the amount of light reflected to
  747. the angle of incidence (the angle made by the light
  748. striking a point on the surface and the normal of that
  749. point). It is not neccessary to understand this.
  750.  
  751.  
  752. Transparent surfaces
  753.  
  754. As well as all the above a surface can have associated
  755. with it a transmissive value, in other words its degree
  756. of transparency. A value of 1.0 would make the surface
  757. completely invisibile whereas 0 would be completely
  758. solid. The default Geometry engine does not support
  759. transmissive surfaces.
  760.  
  761.  
  762. Using the API
  763.  
  764. Custom tool writers have an easy life as the editor does
  765. most things for you. Most of the time you will be using
  766. only a handfull of calls specifically to do with create
  767. verticies and patches etc. However a full understanding
  768. of how the API works is useful for when you want to
  769. expand your tool writing to cover more advanced topics.
  770. See the separate section `Writing custom tools'.
  771.  
  772. Application writers using the API will need a full
  773. understanding of the API, as will those developing new
  774. Geometry engines.
  775.  
  776. The first call to the Geometry DLL must be Initialise,
  777. and it can only be called once. The last call must be
  778. Terminate. No furthers calls can be made after a
  779. Terminate. After Initialise the next likely call that a
  780. standalone application is likely to make will probably be
  781. AddCoorSystem, since every object must belong to a
  782. coordinate system. If we're writing a tool this would
  783. have been done for us by the editor. As explained
  784. coordinate systems are built up in heirarchies. A top
  785. level coordinate system has HCSYS_TOP (a constant defined
  786. in `geometry.h') as its parent. Other coordinate systems
  787. defined underneath these are known as its children.
  788.  
  789. After creating some patches you can render an image by
  790. placing the camera into one of these coordinate systems
  791. using the SetCamera call and then call Render. Again,
  792. custom tools writers wont need to worry about this. When
  793. a coordinate system is rendered everything in it, its
  794. child coordinate systems and everything in them, and its
  795. parent coordinate systems and everything in them are
  796. rendered. The only thing which isn't rendered are other
  797. top level coordinate systems. So each top level
  798. coordinate system can be considered a completely separate
  799. scene, much like separate documents in a word processor.
  800. The one that gets rendered is the one we SetCamera into.
  801.  
  802. The image gets rendered into a windows Device Independent
  803. Bitamp (DIB) which is created on the Render call. The
  804. application can maintain as many DIBs or rendered images
  805. as it likes. Notice how the editor does this. It has at
  806. least one for each top level coordinate system. When the
  807. window's window needs to be painted (on the WM_PAINT
  808. message) with the bitmap, we can call another Geometry
  809. function, UpdateImage, to transfer the image to the
  810. screen.
  811.  
  812. Geometry API Reference
  813.  
  814. To use the Geometry API either from your own application
  815. or from a custom tool, you must include the `geometry.h'
  816. C++ include file and link to `geometry.lib'. All Geometry
  817. functions return a GeomErr value. Usually this will be
  818. GERR_OK (value 0) if the function succeeded otherwise
  819. will either represent an internal processing error such
  820. as `out of memory', or information such as `vertex not
  821. visible'. The calling code should check these return
  822. codes and display any serious internal errors to the user
  823. in a message box. The GetErrorText function can be used
  824. to get a complete text description of the error and
  825. whereabouts internally it occurred. Internal processing
  826. errors more often than not indicate a bug in the calling
  827. code, such as trying to create a patch out of just two
  828. verticies. When your code is debugged they should go
  829. away. If serious errors persist when they shouldn't do we
  830. would be gratefull if you could fill in a bug report form
  831. and send it to us, in order for us to correct bugs in
  832. subsequent releases. We will also endevour to send you an
  833. update as soon as the bug is fixed.
  834.  
  835. Many functions accept handles to objects. It is the
  836. responsibility of the tool/application writers to ensure
  837. that these handles are valid, because although there is a
  838. `handle not valid' error, you cannot rely on the Geometry
  839. engine being able to check its validity.
  840.  
  841.  
  842. Use of C++ maths classes
  843.  
  844. Often a Geometry function will require a C++ class
  845. defined in the maths library as a parameter, a Vec for
  846. instance would be passed to AddVertex. A pure C interface
  847. will soon be made available where instead you will pass a
  848. pointer to a maths `Vector' structure.
  849.  
  850.  
  851.  
  852. Global functions
  853.  
  854.  
  855. GeomErr Initialise (void);
  856. Comments
  857.  
  858. Called to initilise Geometry.  Must be called first.
  859.  
  860. Return codes
  861.  
  862. GERR_OUT_OF_MEMORY
  863.  
  864.  
  865.  
  866.  
  867. GeomErr Terminate (void);
  868.  
  869. Comments
  870.  
  871. Called to terminate Geometry and release all its
  872. allocated resource.  Must be called last.
  873.  
  874. Return codes
  875.  
  876.  
  877.  
  878.  
  879. GeomErr DefSurfType (SurfType *pst, HanSurf *phsur);
  880.  
  881. pst            Pointer to a SurfType structure.
  882.  
  883. phsur               Returns a handle to a surface type.
  884.  
  885. Comments
  886.  
  887. Creates a surface type definition.
  888.  
  889. Return codes
  890.  
  891. GERR_OUT_OF_MEMORY
  892. GERR_TOO_MANY_SURFACE_TYPES
  893. GERR_BITMAP_FILE_NOT_FOUND
  894. GERR_NOT_A_BMP_FILE
  895.  
  896.  
  897.  
  898.  
  899. GeomErr DelSurfType (HanSurf hsur);
  900.  
  901. hsur           Handle to surface type to delete.
  902.  
  903. Comments
  904.  
  905. Deletes a surface type as long as no patches are using
  906. it.
  907.  
  908. Return codes
  909.  
  910. GERR_INVALID_HANDLE
  911. GERR_IN_USE
  912.  
  913.  
  914.  
  915.  
  916. GeomErr QrySurfType (HanSurf hsur,
  917.                      SurfType *pst,
  918.                      BITMAPINFOHEADER *pbmih,
  919.                      ulong *pulNumPats);
  920.  
  921. hsur          Handle to surface type to query.
  922.  
  923. pst           SurfType structure to receive the
  924.               information about the surface.
  925.  
  926. pbmih         Pointer to windows BITMAPINFOHEADER
  927.               structure which will receive details of
  928.               the texture bitmap if appropriate.
  929.  
  930. pulNumPats    Number of patches using this surface.
  931.  
  932. Comments
  933.  
  934. Queries information about a given surface type.
  935.  
  936. Return codes
  937.  
  938. GERR_INVALID_HANDLE
  939.  
  940.  
  941.  
  942.  
  943. GeomErr ModSurfType (HanSurf hsur,
  944.                      SurfType *pst);
  945.  
  946. hsur          Handle to surface type to modify.
  947.  
  948. pst           SurfType structure used to set surface
  949.               characteristics.
  950.  
  951. Comments
  952.  
  953. Modifys a surface type.
  954.  
  955. Return codes
  956.  
  957. GERR_INVALID_HANDLE
  958.  
  959.  
  960.  
  961.  
  962. GeomErr SetCamera (HanCoorSys hcsys,
  963.                    Vec &vecPos,
  964.                    Vec &vecDir,
  965.                    Vec &vecUp);
  966.  
  967. hcsys               Coordinate system to set the camera
  968. in.
  969.  
  970. vecPos              The position of the camera within
  971. this coordinate system.
  972.  
  973. vecDir        The direction in which the camera is
  974.               facing. It takes the form of an absolute
  975.               3D position within the coordinate system.
  976.  
  977. vecUp         The direction which will be `up' in the
  978.               rendered image.  It takes the form of an
  979.               absolute 3D position within the coordinate
  980.               system.
  981.  
  982. usResX        The x resolution of the associated image.
  983.  
  984. usResY        The y resolution of the associated image.
  985.  
  986. Comments
  987.  
  988. Sets the camera at a position within the coordinate
  989. system. The camera can only be in one coordinate system
  990. object at a time. Setting it in another coordinate system
  991. will remove it from this one. If you need to use
  992. Get3DLine and Get3DPoint to get 2D screen coordinates of
  993. 3D points, you must SetCamera first into the appropriate
  994. coordinate system. You must also supply the size of the
  995. image associated with the coordinate system otherwise the
  996. coordinates returned by these functions will be invalid.
  997. These values can be ignored if you do not intend to use
  998. Get3DPoint or Get3DLine.
  999.  
  1000. Return codes
  1001.  
  1002.  
  1003.  
  1004.  
  1005. GeomErr Render (BITMAPINFO *huge *ppbmi,
  1006.                 ushort usResX,
  1007.                 ushort usResY);
  1008.  
  1009. ppbmi               Pointer to a pointer to a windows
  1010. DIB.
  1011.  
  1012. usResX        Requested x resolution of the bitmap. This
  1013.               value must be a multiple of 4 pixels.
  1014.  
  1015. usResY         Requested y resolution of the bitmap.
  1016.  
  1017. Comments
  1018.  
  1019. Before rendering the *ppbmi value should be set to NULL.
  1020. This will cause Geometry to create a DIB of the requested
  1021. size and return a pointer to it in *ppbmi. On subsequent
  1022. renders if we pass in the same value of *ppbmi Geometry
  1023. will reusue the bitmap. If the requested size changes or
  1024. circumstances within Geometry change, for instance,
  1025. implementation specific options allow the default
  1026. Geometry engine to switch between 8 and 24 bit output,
  1027. then the old bitmap is freed and a new bitmap created.
  1028. Each time we pass a value of zero, we force a new bitmap
  1029. to be created. To transfer the image to a device context
  1030. such as the screen, call the UpdateImage function.
  1031.  
  1032. The render bitmaps created by this call are removed by
  1033. Geometry when Terminate is called, however since these
  1034. bitmaps can be very large it is advisable to remove them
  1035. if no longer required by calling DeleteRenBitmap.
  1036.  
  1037. The default Geometry engine is very sensitive about the
  1038. `handedness' of the coordinate systems being rendered.
  1039. When creating a coordinate system it has no way of
  1040. telling if the coordinate system you've created is really
  1041. of the type you've told it. Since Geometry's renderer
  1042. relies on this information to optimise its performance it
  1043. is likely to cause a trap if say, you created a left hand
  1044. coordinate system but told Geometry it is right handed.
  1045. If you experience traps when rendering check your
  1046. coordinate systems very carefully.
  1047.  
  1048. Return codes
  1049.  
  1050. GERR_IMAGE_SIZE_NOT_MULT_4
  1051. GERR_BITMAP_TOO_SMALL
  1052. GERR_TOO_MANY_BITMAPS
  1053.  
  1054.  
  1055.  
  1056.  
  1057. GeomErr DeleteRenBitmap (BITMAPINFO huge *pbmi);
  1058.  
  1059. pbmi           A pointer the the BITMAPINFO structure
  1060. created by the Render call.
  1061.  
  1062. Comments
  1063.  
  1064. Tells Geometry to remove a bitmap created by the Render
  1065. call.
  1066.  
  1067. Return codes
  1068.  
  1069.  
  1070.  
  1071.  
  1072. GeomErr UpdateImage (ulong ulHDC,
  1073.                      BITMAPINFO huge *pbmi,
  1074.                      ushort usX,
  1075.                      ushort usY);
  1076.  
  1077. ulHDC          A ulong value holding the HDC to paint the
  1078. rendered image to.
  1079.  
  1080. pbmi           Pointer to the rendered DIB (created by
  1081. calling Render).
  1082.  
  1083. usX           Horizontal position in the DC of where the
  1084.               image will appear.
  1085.  
  1086. usY           Vertical position in the DC of where the
  1087.               image will appear.
  1088.  
  1089. Comments
  1090.  
  1091. Transfers a rendered DIB to a device context. This call
  1092. could result in realising the colour palette.
  1093.  
  1094. Return codes
  1095.  
  1096.  
  1097.  
  1098.  
  1099. GeomErr GetErrorText (GeomErr gerr,
  1100.                      char *szBuff,
  1101.                      ushort usBuffSize);
  1102.  
  1103. gerr           The GeomErr value returned from a Geometry
  1104. call.
  1105.  
  1106. szBuff              Pointer to a character buffer to hold
  1107. the error string.
  1108.  
  1109. usBuffSize          Set to indicate the size of szBuff.
  1110.  
  1111. Comments
  1112.  
  1113. Can be called to get Geometry to return an error string
  1114. describing the error which occurred. The string will
  1115. contain the name of the module and the line number on
  1116. which the error occurred.
  1117.  
  1118. Return codes
  1119.  
  1120. GERR_BUFFER_TOO_SMALL
  1121.  
  1122.  
  1123.  
  1124. Coordinate system functions
  1125.  
  1126.  
  1127. GeomErr AddCoorSys (HanCoorSys hcsysParent,
  1128.                      Mat &matToParent,
  1129.                      Mat &matFromParent,
  1130.                      ushort usType,
  1131.                      HanCoorSys *phcsys);
  1132.  
  1133. hcsysParent        Handle to parent coordinate system
  1134.  
  1135. matToParent   Matrix describing the transformation from
  1136.               child to parent. In other words this
  1137.               matrix transforms a point in the child
  1138.               coordinate system to its corresponding
  1139.               position relative to the parent coordinate
  1140.               system.
  1141.  
  1142. matFromParent The inverse or opposite matrix to
  1143.               matToParent. NB. The maths library can
  1144.               easily generate the inverse of a matrix by
  1145.               preeceeding it with a minus sign (eg. -
  1146.               mat).
  1147.  
  1148. usType             This value indicates wether the
  1149.               coordinate system being defined is right
  1150.               handed or left handed. It should be either
  1151.               CT_RIGHTHAND or CT_LEFTHAND.
  1152.  
  1153. phcsys        Returns a handle to a new coordinate
  1154.               system.
  1155.  
  1156. Comments
  1157.  
  1158. Creates a coordinate system as a child of the parent. Use
  1159. HCSYS_TOP to create a top level coordinate system. If the
  1160. matricies do not specifically reverse one of the
  1161. coordinate system axis's then this coordinate system will
  1162. be the same `handedness' as its parent. It is important
  1163. that the usType parameter correctly identifies the type
  1164. of the coordinate system.
  1165.  
  1166. The matricies can define scaling and shearing as well as
  1167. basic orientation. However a matrix is not acceptable if
  1168. it alters the basic topology of the geometry. For
  1169. instance, a mirror type matrix will alter
  1170. the `type' of the coordinate system (only use this if you
  1171. also specify the correct `type' parameter). A matrix that
  1172. warps space into say, a cone or cylindrical shape is
  1173. completely unacceptable. A matrix consisting entirely of
  1174. zeros, would be the Genesis equivalent of a black hole.
  1175. In space physical laws break down inside black holes.
  1176. Genesis will also break down if you use a matrix like
  1177. this!
  1178.  
  1179. Return codes
  1180.  
  1181. GERR_OUT_OF_MEMORY
  1182.  
  1183.  
  1184.  
  1185.  
  1186. GeomErr DelCoorSys (HanCoorSys hcsys);
  1187.  
  1188. hcsys               Coordinate system to delete.
  1189.  
  1190. Comments
  1191.  
  1192. Deletes a coordinate system and any objects belonging to
  1193. that system including child coordinate systems and their
  1194. objects.
  1195.  
  1196. Return codes
  1197.  
  1198.  
  1199.  
  1200.  
  1201. GeomErr QryCoorSys (HanCoorSys hcsys, CoorSysInfo *pcsi);
  1202.  
  1203. hcsys               Coordinate system to query.
  1204.  
  1205. pcsi           Pointer to a CoorSysInfo structure to
  1206. receive the information.
  1207.  
  1208. Comments
  1209.  
  1210. Returns information about a coordinate system and all its
  1211. associated objects enabling us to navigate our way around
  1212. the coordinate system heirarchy.
  1213.  
  1214. If you query HCSYS_TOP, the only relevent field is
  1215. usType, which will be lefthand.
  1216.  
  1217. If you query any top level coordinate systems (ie. direct
  1218. children of HCSYS_TOP) you cannot rely on the matrix
  1219. fields of the CoorSysInfo structure being what you
  1220. originally set them to. The reason for this apparent
  1221. oddity is that under the covers these matricies define
  1222. the position of the scene relative to the camera, so as
  1223. the camera 'moves', so these matricies change.
  1224.  
  1225. Return codes
  1226.  
  1227.  
  1228.  
  1229.  
  1230. GeomErr ModCoorSys (HanCoorSys hcsys,
  1231.                      Mat &matToParent,
  1232.                      Mat &matFromParent,
  1233.                      ushort usTransType);
  1234.  
  1235. hcsys               Coordinate system to query.
  1236.  
  1237. matToParent   Matrix to define the new position of the
  1238.               coordinate system relative to its parent.
  1239.               It can be used either to replace the old
  1240.               matrix or to modify it.
  1241.  
  1242. matFromParent  Inverse of matToParent.
  1243.  
  1244. usTransType   Indication of how the new matrix is to
  1245.               modify the existing one. Can be one of the
  1246.               following values;
  1247.  
  1248.     MCS_TRANS_LAST      The new matrix is applied as;
  1249. old_matrix*new_matrix
  1250.  
  1251.     MCS_TRANS_FRIST     The new matrix is applied as;
  1252. new_matrix*old_matrix
  1253.  
  1254.     MCS_TRANS_REPLACE   The new matrix simply replaces
  1255. the old
  1256.  
  1257. Comments
  1258.  
  1259. Modifies the position of a coordinate system relative to
  1260. its parent.
  1261.  
  1262. Return codes
  1263.  
  1264. GERR_INVALID_OPP_IN_TOP
  1265.  
  1266.  
  1267.  
  1268.  
  1269. GeomErr Get3DLine (HanCoorSys hcsys,
  1270.                    Vec &vecA,
  1271.                    Vec &vecB,
  1272.                    float *pfStartX,
  1273.                    float *pfStartY,
  1274.                    float *pfEndX,
  1275.                    float *pfEndY);
  1276.  
  1277. hcsys               Handle of coordinate system points
  1278. belong to.
  1279.  
  1280. vecA           Position in coordinate system of first
  1281. point.
  1282.  
  1283. vecB           Position in coordinate system of second
  1284. point.
  1285.  
  1286. pfStartX       Returns the screen X coordinate of start
  1287. of line.
  1288.  
  1289. pfStartY       Returns the screen Y coordinate of start
  1290. of line.
  1291.  
  1292. pfEndX         Returns the screen X coordinate of end of
  1293. line.
  1294.  
  1295. pfEndY         Returns the screen Y coordinate of end of
  1296. line.
  1297.  
  1298. Comments
  1299.  
  1300. Returns the 2D screen coordinates of a line segment
  1301. defined by two points; vecA and vecB, within the
  1302. coordinate system hcsys. This routine can be used to
  1303. generate lines corresponding to points in a rendered
  1304. image which can then be superimposed on the rendered
  1305. image. This way it makes it look as if Geometry's
  1306. renderer can support 3D lines as well as patches. Of
  1307. course this is not quite true as the lines do not go
  1308. through the hidden surface/line process.
  1309.  
  1310. Unlike the 2D screen coordinates returned on calls like
  1311. QryVertex, this routine doesn't require a Render to have
  1312. taken place, however it does require that the camera is
  1313. set in an appropriate coordinate system for the point to
  1314. be visible, otherwise GERR_NOT_VISIBLE is returned.
  1315.  
  1316. Return codes
  1317.  
  1318. GERR_NOT_VISIBLE
  1319.  
  1320.  
  1321.  
  1322.  
  1323. GeomErr Get3DPoint (HanCoorSys hcsys,
  1324.                     Vec &vec,
  1325.                     float *pfX,
  1326.                     float *pfY);
  1327.  
  1328. hcsys               Handle of coordinate system points
  1329. belong to.
  1330.  
  1331. vec            Position of point in coordinate system.
  1332.  
  1333. pfX            Returns the screen X coordinate of the
  1334. point.
  1335.  
  1336. pfY            Returns the screen Y coordinate of the
  1337. point.
  1338.  
  1339. Comments
  1340.  
  1341. Returns the 2D screen coordinates of a point; vec, within
  1342. the coordinate system hcsys.
  1343.  
  1344. Unlike the 2D screen coordinates returned on calls like
  1345. QryVertex, this routine doesn't require a Render to have
  1346. taken place, however it does require that the camera is
  1347. set in an appropriate coordinate system for the point to
  1348. be visible, otherwise GERR_NOT_VISIBLE is returned.
  1349.  
  1350. Return codes
  1351.  
  1352. GERR_NOT_VISIBLE
  1353.  
  1354.  
  1355.  
  1356. Object construction functions
  1357.  
  1358.  
  1359. GeomErr AddObject (HanCoorSys hcsys,
  1360.                    float fNewVertTol,
  1361.                    HanObject *phobj);
  1362.  
  1363. hcsys               Handle to coordinate system to add
  1364. object to.
  1365.  
  1366. fNewVertTol         Verticies in this object cannot be
  1367. closer than this value in all of x, y and z.
  1368.  
  1369. phobj               Returns a handle to the new object.
  1370.  
  1371. Comments
  1372.  
  1373. Adds a new object to a coordinate system.
  1374.  
  1375. When new verticies are added to this object a check is
  1376. made to see if it is closer than fNewVertTol in x, y and
  1377. z. If it is the vertex is re-used. Notice that
  1378. fNewVertTol is not the distance from the existing
  1379. verticies, this is given by the formula;
  1380. MaxDistFromVert=sqrt((NewVertTol^2)*3).
  1381.  
  1382. Return codes
  1383.  
  1384.  
  1385.  
  1386.  
  1387. GeomErr DelObject (HanObject hobj);
  1388.  
  1389. hobj           Handle to the object being deleted.
  1390.  
  1391. Comments
  1392.  
  1393. Deletes an object along with all its patches, verticies
  1394. and normals from a coordinate system.
  1395.  
  1396. Return codes
  1397.  
  1398.  
  1399.  
  1400.  
  1401. GeomErr QryObject (HanObject hobj, ObjectInfo *poi);
  1402.  
  1403. hobj           Handle to the object to query.
  1404.  
  1405. poi            Points to an ObjectInfo structure to
  1406. receive the information.
  1407.  
  1408.  
  1409. Comments
  1410.  
  1411. Returns information on an object.
  1412.  
  1413. Return codes
  1414.  
  1415.  
  1416.  
  1417.  
  1418. GeomErr PrtObject (HanObject hobj);
  1419.  
  1420. hobj           Handle to the object to print.
  1421.  
  1422. Comments
  1423.  
  1424. Used purely as a debugging aid for when writting Geometry
  1425. engines. This routine can be called to print out a text
  1426. description of an objects data structures. It can be
  1427. invoked from the editor using a special key combination.
  1428. Unless compiled with the _DEBUG macro definition this
  1429. routine should do nothing.
  1430.  
  1431. Return codes
  1432.  
  1433.  
  1434.  
  1435.  
  1436. GeomErr AddVertex (HanObject hobj,
  1437.                    Vec &vec,
  1438.                    HanVertex *phver);
  1439.  
  1440. hobj           Handle to object to add vertex to.
  1441.  
  1442. vec            3D position of the vertex within the
  1443. coordinate system.
  1444.  
  1445. phver               Returns a handle to the vertex.
  1446.  
  1447. Comments
  1448.  
  1449. Creates a new vertex belonging to the object.
  1450.  
  1451. Return codes
  1452.  
  1453.  
  1454.  
  1455.  
  1456. GeomErr DelVertex (HanObject hobj, HanVertex hver);
  1457.  
  1458. hobj           Handle to object we want to delete the
  1459. vertex from.
  1460.  
  1461. hver           Handle to the vertex to be deleted.
  1462.  
  1463. Comments
  1464.  
  1465. Deletes a vertex from an object. The vertex is only
  1466. deleted if no patches are using it.
  1467.  
  1468. Return Codes
  1469.  
  1470. GERR_IN_USE
  1471.  
  1472.  
  1473.  
  1474. GeomErr QryVertex (HanObject hobj,
  1475.                    HanVertex hver,
  1476.                    VertInfo *pvi);
  1477.  
  1478. hobj           Handle to object containg vertex to query.
  1479.  
  1480. hver           Handle to the vertex to query.
  1481.  
  1482. pvi            Pointer to a VertInfo structure to receive
  1483. the information.
  1484.  
  1485. Comments
  1486.  
  1487. Returns information about a vertex. The fScrnX and fScrnY
  1488. elements of the VertInfo structure contain the screen x
  1489. and y coordinates of this vertex the last time a render
  1490. was performed. If the vertex was not visible for whatever
  1491. reason, eg. it was out of view, or the last render was
  1492. applied to a different coordinate system, then
  1493. GERR_NOT_VISIBLE is returned.
  1494.  
  1495. The default Geometry engine will indicate that this
  1496. vertex was visible if it was within the view and used by
  1497. a patch which was facing the viewpoint even if the vertex
  1498. was obscurred by a closer object.
  1499.  
  1500. Return codes
  1501.  
  1502. GERR_NOT_VISIBLE
  1503.  
  1504.  
  1505.  
  1506.  
  1507. GeomErr ModVertex (HanObject hobj,
  1508.                     HanVertex hver,
  1509.                     Vec &vec);
  1510.  
  1511. hobj           Handle to object containing vertex to
  1512. modify.
  1513.  
  1514. hver           Handle to vertex to modify.
  1515.  
  1516. vec            New position.
  1517.  
  1518. Comments
  1519.  
  1520. Modifies the position of a vertex. The next time a render
  1521. is performed the vertex will appear in its new position.
  1522. If the new position affects a patch with 4 or more sides,
  1523. such that it no longer lies on a plane, then
  1524. GERR_NOT_ON_PLANE is returned.
  1525.  
  1526. Return codes
  1527.  
  1528. GERR_NOT_ON_PLANE
  1529.  
  1530.  
  1531.  
  1532.  
  1533. GeomErr AddNormal (HanObject hobj
  1534.                     Vec &vec,
  1535.                     HanNormal *phnor);
  1536.  
  1537. hobj           Handle to the object to add the normal to.
  1538.  
  1539. vec                3D direction vector of the normal. It
  1540.               specifies a 3D `direction' rather than an
  1541.               absolute point in 3D space.
  1542.  
  1543. phnor               Returns a handle to the new normal.
  1544.  
  1545. Comments
  1546.  
  1547. Adds a normal to an object.
  1548.  
  1549. Return codes
  1550.  
  1551.  
  1552.  
  1553.  
  1554. GeomErr DelNormal (HanObject hobj, HanNormal hnor);
  1555.  
  1556. hobj           Handle to the object containing the normal
  1557. to delete.
  1558.  
  1559. hnor           Handle to the normal to delete.
  1560.  
  1561. Comments
  1562.  
  1563. Deletes a normal from an object as long as no patches are
  1564. using it.
  1565.  
  1566. Return Codes
  1567.  
  1568. GERR_IN_USE
  1569.  
  1570.  
  1571.  
  1572.  
  1573. GeomErr QryNormal (HanObject hobj,
  1574.                     HanNormal hnor,
  1575.                     HanVertex hver,
  1576.                     NormInfo *pni);
  1577.  
  1578. hobj           Handle to the object containing the normal
  1579. to query.
  1580.  
  1581. hnor           Handle to normal to query.
  1582.  
  1583. hver               Handle to a vertex using the normal
  1584.               in order to generate the screen positions
  1585.               for the last render.
  1586.  
  1587. pni            Pointer to a NormInfo structure to receive
  1588. the information.
  1589.  
  1590. Comments
  1591.  
  1592. Returns information about a normal. Since a single normal
  1593. can be used by verticies from many patches we need to
  1594. supply the handle of a vertex in order to generate the 2D
  1595. screen coordinates of the normal when used by that
  1596. vertex. The normal makes a line extending from the vertex
  1597. to a distance of 1 coordinate system unit away in the 3D
  1598. direction given when the normal was created. If this line
  1599. or any part of it was visible at the last render, its 2D
  1600. screen coordinates are returned, otherwise the return
  1601. code is GERR_NOT_VISIBLE.
  1602.  
  1603. Return Codes
  1604.  
  1605. GERR_NOT_VISIBLE
  1606.  
  1607.  
  1608.  
  1609.  
  1610. GeomErr ModNormal (HanObject hobj,
  1611.                     HanNormal hnor,
  1612.                     Vec &vec);
  1613.  
  1614. hobj           Handle to the object containing the
  1615. normal.
  1616.  
  1617. hnor           Handle to normal to modify.
  1618.  
  1619. vec            New direction vector.
  1620.  
  1621. Comments
  1622.  
  1623. Modifies the direction of a normal vector and therefore
  1624. the surface gradient at all verticies using the normal.
  1625. At the next render the shading at all those verticies
  1626. using the normal will have changed to reflect the new
  1627. surface gradients.
  1628.  
  1629. Return codes
  1630.  
  1631.  
  1632.  
  1633.  
  1634. GeomErr QryEdge (HanObject hobj,
  1635.                  HanEdge hedg,
  1636.                  EdgeInfo *pei);
  1637.  
  1638. hobj           Handle to the object cotining the edge.
  1639.  
  1640. hedg           Handle to the edge to be queried.
  1641.  
  1642. pei            Pointer to an EdgeInfo structure to
  1643. receive the information.
  1644.  
  1645. Comments
  1646.  
  1647. Returns information about an edge. Although we do not
  1648. explicitly create the edges, we create verticies and
  1649. patches and Geometry takes care of the edges, it is
  1650. sometimes useful to have access to the edges. Suppose we
  1651. want to draw a wire frame of the object (exactly as the
  1652. editor does). We could iteratively query each patch in
  1653. the object, query the screen positions of each of its
  1654. verticies in turn and draw them. However each edge of
  1655. each patch is also used by another patch meaning each
  1656. edge (and therefore the entire object) will get drawn
  1657. twice. Querying the edges directly avoids this.
  1658.  
  1659. Return codes
  1660.  
  1661.  
  1662.  
  1663.  
  1664. GeomErr DefPatch (HanObject hobj,
  1665.                   ushort usNumEdges,
  1666.                   ushort usFlags,
  1667.                   float fSmoothAng,
  1668.                   HanVertex *ahver,
  1669.                   HanNormal *ahnor,
  1670.                   HanSurf hsur,
  1671.                   ushort *pusNumPats,
  1672.                   HanPatch *ahpat);
  1673.  
  1674. hobj           Handle to object to add patch to.
  1675.  
  1676. usNumEdges    The number of edges, and therefore
  1677.               verticies and normals in the patch. This
  1678.               can be any number from 3 upwards. If the
  1679.               Geometry engine does not support patches
  1680.               of more than say 3 or 4 edges then the
  1681.               patch will be automatically split up into
  1682.               more than one patch resulting in more than
  1683.               one handle being returned.
  1684.  
  1685. usFlags       Flags controlling the creation of the
  1686.               patch. It can be any of the following
  1687.               values combined with C's OR operator
  1688.               (`|');
  1689.  
  1690.  DP_AUTOSMOOTH    Signifies that the patch should
  1691.                    appear curved even although we have
  1692.                    not defined any normals. The normals
  1693.                    should be created automatically by
  1694.                    Geometry by averaging out the plane
  1695.                    normals of all patches converging on
  1696.                    a vertex.
  1697.  
  1698.  DP_SMOOTH_BY_SURFSignifies that autosmoothing is
  1699.                    applied only to patches ajoining this
  1700.                    one if they have the same surface
  1701.                    type.
  1702.  
  1703.  DP_SMOOTH_BY_ANGLE    Signifies that autosmoothing is
  1704.                    applied only to patches ajoining this
  1705.                    one if they angle made at the join is
  1706.                    less than that given by the
  1707.                    fSmoothAng paramter.
  1708.  
  1709.  DP_DONT_VALIDATE Signifies that this patch should not
  1710.                    be validated. If you code is fully
  1711.                    debugged and tested it can use this
  1712.                    flag to say, `I am confident that
  1713.                    this patch definition is OK'. Using
  1714.                    this flag speeds up the creation
  1715.                    process, otherwise the following
  1716.                    checks are performed;
  1717.  
  1718.                     ·    No two points can be in exactly the same spot
  1719.                     ·    All points do not lie along a straight line
  1720. ·    All points lie on a plane (or within a small
  1721. tolerence of)
  1722.  
  1723.  DP_CONVEX        Signifies that the polygon is convex
  1724.                    (has no internal angles greater than
  1725.                    180 degrees). This flag should not be
  1726.                    used if we're not certain. As with
  1727.                    DP_DONT_VALIDATE it can speed up the
  1728.                    creation process, (depending on the
  1729.                    Geometry engine).
  1730.  
  1731. fSmoothAng    Specifies the angle to use for
  1732.               autosmoothing. Only takes effect if
  1733.               DP_SMOOTH_BY_ANGLE is used.
  1734.  
  1735. ahver         Array of handles to verticies. The number
  1736.               of verticies is given by the usNumEdges
  1737.               parameter. The verticies must be specified
  1738.               in a clockwise order when viewing the
  1739.               patch from the correct side. No attempt
  1740.               should be made to define a patch using
  1741.               verticies belonging to another object.
  1742.  
  1743. ahnor         Array of handles to normals. The number of
  1744.               normals is given by the usNumEdges
  1745.               parameter. Each normal relates to the
  1746.               corresponding vertex in ahver, eg.
  1747.               ahnor[0] applies to aver[0] etc. This
  1748.               parameter is ignored if the DP_AUTOSMOOTH
  1749.               flag is given. No attempt should be made
  1750.               to define a patch using normals belonging
  1751.               to another object.
  1752.  
  1753. hsur          Handle to the surface type to be used for
  1754.               the patch.
  1755.  
  1756. pusNumPats    A pointer to a ushort used to return the
  1757.               number of patches actually created (Large
  1758.               concave outlines will almost definitely be
  1759.               split up into more than one patch). Before
  1760.               calling the ushort should be set to the
  1761.               size of the ahpat buffer.
  1762.  
  1763. ahpat         Buffer to hold the handle(s) of the
  1764.               patch(es) created.
  1765.  
  1766. Comments
  1767.  
  1768. Creates a patch out of  3 or more predfined verticies.
  1769. Any number of verticies can be used to define the outline
  1770. of the patch as long as they lie on a plane, do not form
  1771. a straight line or cross over at any point. The
  1772. autosmooth feature takes the worry out of having to
  1773. define normals for curved surfaces.
  1774.  
  1775. The outline may be split into more than one patch
  1776. depending on how many verticies the Geometry engine can
  1777. use in a single patch and wether or not it can support
  1778. concave patch outlines. The default Geometry engine
  1779. supports patches of no more than four verticies and they
  1780. must be convex. An attempt to create a patch with more
  1781. than four verticies, or with a concave outline will
  1782. result in more than one patch being created.
  1783.  
  1784. Return codes
  1785.  
  1786. GERR_COINCIDENT_POINTS
  1787. GERR_THIN_SEGMENT
  1788. GERR_NOT_ON_PLANE
  1789. GERR_OUT_OF_MEMORY
  1790. GERR_BUFFER_TOO_SMALL
  1791. GERR_NOT_ENOUGH_POINTS
  1792.  
  1793.  
  1794.  
  1795.  
  1796. GeomErr DelPatch (HanObject hobj, HanPatch hpat);
  1797.  
  1798. hobj           Handle to the object containing the patch
  1799. to delete.
  1800.  
  1801. hpat           Handle to the patch to delete.
  1802.  
  1803. Comments
  1804.  
  1805. Deletes a patch from an object.
  1806.  
  1807. Return codes
  1808.  
  1809.  
  1810.  
  1811.  
  1812. GeomErr QryPatch (HanObject hobj,
  1813.                   HanPatch hpat,
  1814.                   PatchInfo *ppi);
  1815.  
  1816. hobj           Handle to the object containing the patch
  1817. to query.
  1818.  
  1819. hpat           Handle to the patch to query.
  1820.  
  1821. ppi           Pointer to a PatchInfo structure to hold
  1822.               the information. The ahver and ahnor
  1823.               elements should point to buffers to
  1824.               receive the handles of the verticies and
  1825.               normals and the usNumEdges element should
  1826.               indicate how many handles there is room
  1827.               for in the buffers. NB. No Geometry engine
  1828.               implementation should have more than
  1829.               MAX_PATCH_EDGES edges in any patch
  1830.               (defined in geometry.h), so it is a good
  1831.               idea to set usNumEdges to this.
  1832.  
  1833. Comments
  1834.  
  1835. Returns information about a patch.
  1836.  
  1837. Return codes
  1838.  
  1839. GERR_BUFFER_TOO_SMALL
  1840.  
  1841.  
  1842.  
  1843.  
  1844. GeomErr QryVertPatch (ulong *pulRef, HanPatch *phpat);
  1845.  
  1846. pulRef        Pointer to a ulong holding a reference to
  1847.               a patch. This value is returned by the
  1848.               ulRef element of the VertInfo structure on
  1849.               a call to QryVertex.
  1850.  
  1851. phpat               Returns a handle to the next patch
  1852. using this vertex.
  1853.  
  1854. Comments
  1855.  
  1856. To query which patches use a particular vertex, first
  1857. query the vertex, and then pass the ulRef value to
  1858. QryVertPatch. This will return a handle to the first
  1859. patch using that vertex. Subsequent calls to QryVertex
  1860. will return other patches until a NULL_HANDLE is
  1861. returned.
  1862.  
  1863. Return codes
  1864.  
  1865.  
  1866.  
  1867. Lighting functions
  1868.  
  1869.  
  1870. GeomErr AddLight (HanCoorSys hcsys,
  1871.                   LightDef *pld,
  1872.                   HanLight *phli);
  1873.  
  1874. hcsys               Handle to coordinate system to add
  1875. light to.
  1876.  
  1877. pld            Points to a LightDef structure containing
  1878. details of the light.
  1879.  
  1880. phli           Returns a handle to a new light.
  1881.  
  1882. Comments
  1883.  
  1884. Creates a new light belonging to the coordinate system.
  1885.  
  1886. Return codes
  1887.  
  1888.  
  1889.  
  1890.  
  1891. GeomErr DelLight (HanLight hli);
  1892.  
  1893. hli            Handle to the light to be deleted.
  1894.  
  1895. Comments
  1896.  
  1897. Deletes a light from the coordinate system.
  1898.  
  1899. Return Codes
  1900.  
  1901.  
  1902.  
  1903.  
  1904. GeomErr QryLight (HanLight hli, LightDef *pld);
  1905.  
  1906. hli            Handle to light to query.
  1907.  
  1908. pld            Pointer to a LightDef structure to receive
  1909. the information.
  1910.  
  1911. Comments
  1912.  
  1913. Returns information about a light.
  1914.  
  1915. Return codes
  1916.  
  1917.  
  1918.  
  1919.  
  1920. GeomErr ModLight (HanLight hli, LightDef *pld);
  1921.  
  1922. hli            Handle to light to modify.
  1923.  
  1924. pld            Pointer to LightDef structure containing
  1925. the new parameters.
  1926.  
  1927. Comments
  1928.  
  1929. Modifies the characteristics of a light, including
  1930. possibly its position.
  1931.  
  1932. Return codes
  1933.  
  1934.  
  1935.  
  1936.  
  1937. GeomErr SetAmbient (float fInt);
  1938.  
  1939. fInt           Ambient light intensity.
  1940.  
  1941. Comments
  1942.  
  1943. Sets the intensity of the ambient light in a scene. The
  1944. ambient value applies to all coordinates systems.
  1945.  
  1946. Return codes
  1947.  
  1948. GERR_INVALID_LIGHT_INT
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955. Loading and Saving
  1956.  
  1957.  
  1958. GeomErr SaveScene (HFILE hfile,
  1959.                    HanCoorSys hcsys,
  1960.                    ulong *pulNumCSys,
  1961.                    HanCoorSys *ahcsys,
  1962.                    ulong *pulNumObjs,
  1963.                    HanObject *ahobj)
  1964.  
  1965. hfile         Handle of a file to save to.
  1966.  
  1967. hcsys         Coordinate system to save.
  1968.  
  1969. pulNumCSys    Indicates the size of the ahcsys buffer in
  1970.               terms of how many handles it can hold. On
  1971.               return this value is modified to the total
  1972.               number of coordinate systems saved, and
  1973.               therefore the number of handles in the
  1974.               ahcsys array.
  1975.  
  1976. ahcsys        An array which on return contains the
  1977.               handles of all the coordinate systems
  1978.               saved in the order in which they were
  1979.               saved in the file. If you are not
  1980.               interested in the handles, this parameter
  1981.               can be NULL if we set *pulNumCSys to zero.
  1982.  
  1983. pulNumObjs    Indicates the size of the ahobj buffer in
  1984.               terms of how many handles it can hold. On
  1985.               return this value is modified to the total
  1986.               number of objects saved, and therefore the
  1987.               number of handles in the ahobj array.
  1988.  
  1989. ahobj         An array which on return contains the
  1990.               handles of all the objects saved in the
  1991.               order in which they were saved in the
  1992.               file. If you are not interested in the
  1993.               handles, this parameter can be NULL if we
  1994.               set *pulNumObjs to zero.
  1995.  
  1996. Comments
  1997.  
  1998. Saves a coordinate system to the file given by hfile. All
  1999. objects and lights belonging to this coordinate system
  2000. will be saved including any children and all their
  2001. objects. The last four parameters will return the
  2002. handles of all coordinate systems and objects saved. This
  2003. is very usefull for applications like the editor. The
  2004. editor associates a name with each coordinate system and
  2005. object. These names are unknown to Geometry and so will
  2006. not get saved. However the editor can save the names
  2007. associated with each handle after the main Geometry
  2008. information in the file. When the file gets loaded again
  2009. by LoadScene we get told the new handles which we then
  2010. simply have to associate with the names in the file.
  2011.  
  2012. Return codes
  2013.  
  2014.  
  2015.  
  2016.  
  2017. GeomErr LoadScene (HFILE hfile,
  2018.                    HanCoorSys hcsys,
  2019.                    Char *szTexPath,
  2020.                    ulong *pulNumCSys,
  2021.                    HanCoorSys *ahcsys,
  2022.                    ulong *pulNumObjs,
  2023.                    HanObject *ahobj)
  2024.  
  2025. hfile         Handle of a file to load from.
  2026.  
  2027. hcsys         Coordinate system to load under.
  2028.  
  2029. szTexPath     A pointer to a path specification for
  2030.               where to search for texture bitmaps if
  2031.               they are not found in the current working
  2032.               directory. This would typically be set to
  2033.               the directory where the model file is, or
  2034.               else a special texture directory. It must
  2035.               have terminating back slash eg;
  2036.               "c:\textures\" or else be a null string.
  2037.               The pointer cannot be NULL.
  2038.  
  2039. pulNumCSys    Indicates the size of the ahcsys buffer in
  2040.               terms of how many handles it can hold. On
  2041.               return this value is modified to the total
  2042.               number of coordinate systems loaded, and
  2043.               therefore the number of handles in the
  2044.               ahcsys array.
  2045.  
  2046. ahcsys        An array which on return contains the
  2047.               handles of all the coordinate systems
  2048.               loaded in the order in which they existed
  2049.               in the file. If you are not interested in
  2050.               the handles, this parameter can be NULL if
  2051.               we set *pulNumCSys to zero.
  2052.  
  2053. pulNumObjs    Indicates the size of the ahobj buffer in
  2054.               terms of how many handles it can hold. On
  2055.               return this value is modified to the total
  2056.               number of objects loaded, and therefore
  2057.               the number of handles in the ahobj array.
  2058.  
  2059. ahobj         An array which on return contains the
  2060.               handles of all the objects loaded in the
  2061.               order in which they existed in the file.
  2062.               If you are not interested in the handles,
  2063.               this parameter can be NULL if we set
  2064.               *pulNumObjs to zero.
  2065.  
  2066. Comments
  2067.  
  2068. Loads a coordinate system from the file given by hfile.
  2069. All objects and lights belongning to this coordinate
  2070. system will be loaded including any children and all
  2071. their objects. The top level coordinate system in the
  2072. file will become a child of hcsys. To load an entirely
  2073. new scene hcsys should be set to HCSYS_TOP. For a fuller
  2074. description of the last four parameters see SaveScene.
  2075.  
  2076. Return codes
  2077.  
  2078. GERR_INVALID_GEN_FILE
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084. Structures and types
  2085.  
  2086.  
  2087. typedef struct Colourtag      // col
  2088.      {
  2089.      byte                byRed;
  2090.      byte                byGrn;
  2091.      byte                byBlu;
  2092.      } Colour;
  2093.  
  2094. byRed               Red component
  2095.  
  2096. byGrn               Green component
  2097.  
  2098. byBlu               Blue component
  2099.  
  2100. Comments
  2101.  
  2102. Specifies a true RGB colour value.
  2103.  
  2104.  
  2105.  
  2106.  
  2107. typedef struct VertInfotag         // vi
  2108.      {
  2109.      Vec                 vec;
  2110.      ulong               ulNumPatches;
  2111.      ulong               ulRef;
  2112.      float                    fScrnX;
  2113.      float                    fScrnY;
  2114.      HanVertex           hverNext;
  2115.      } VertInfo;
  2116.  
  2117. vec           3D position of vertex
  2118.  
  2119. ulNumPatches  Number of patches using this vertex
  2120.  
  2121. ulRef         Reference to the first patch. To find all
  2122.               the patches using this vertex pass this
  2123.               value to QryVertPatch
  2124.  
  2125. fScrnX        The screen X coordinate of this vertex
  2126.               after the last Render call
  2127.  
  2128. fScrnY        The screen Y coordinate of this vertex
  2129.               after the last Render call
  2130.  
  2131. hverNext      Handle to the next vertex in this object
  2132.  
  2133. Comments
  2134.  
  2135. Contains information about a queried vertex.
  2136.  
  2137.  
  2138.  
  2139.  
  2140. typedef struct NormInfotag         // ni
  2141.      {
  2142.      Vec                 vec;
  2143.      HanNormal      hnorNext;
  2144.      } NormInfo;
  2145.  
  2146. vec           3D direction vector of normal
  2147.  
  2148. hnorNext      Handle to next normal in this object
  2149.  
  2150. Comments
  2151.  
  2152. Contains information about a queried normal.
  2153.  
  2154.  
  2155.  
  2156.  
  2157. typedef struct PatchInfotag        // pi
  2158.      {
  2159.      ushort              usNumEdges;
  2160.      ushort              usFlags;
  2161.      HanVertex           *ahver;
  2162.      HanNormal      *ahnor;
  2163.      HanSurf             hsur;
  2164.      Vec                 vecNorm;
  2165.      HanPatch            hpatNext;
  2166.      } PatchInfo;
  2167.  
  2168. usNumEdges    Describes the size of the buffers pointed
  2169.               to by ahver and ahnor
  2170.  
  2171. usFlags       Set of bitwise OR'd flags describing the
  2172.               patch;
  2173.  
  2174.  PI_VISIBLE       Patch was visible at last render. The
  2175.                    default geometry engine sets this on
  2176.                    if the patch was facing us, but was
  2177.                    maybe obscured by a closer object
  2178.  
  2179.  PI_FLAT          If on object is flat, otherwise it is
  2180.                    curved
  2181.  
  2182. ahver         Pointer to a buffer in which the handles
  2183.               of the verticies will be returned
  2184.  
  2185. ahnor         Pointer to a buffer in which the handles
  2186.               of the normals will be returned
  2187.  
  2188. hsur          Handle to the surface used by the patch
  2189.  
  2190. vecNorm       Normal of the plane of the patch
  2191.  
  2192. hpatNext      Handle to the next patch in the object
  2193.  
  2194. Comments
  2195.  
  2196. Contains information about a quieried patch. The ahver
  2197. and ahnor pointers should be set to point to the buffers
  2198. to receive the handles before the query call and
  2199. usNumEdges variable be set to the size of the ahver and
  2200. ahnor buffers.
  2201.  
  2202.  
  2203.  
  2204.  
  2205. typedef struct EdgeInfotag         // ei
  2206.      {
  2207.      HanVertex           hverA;
  2208.      HanVertex           hverB;
  2209.      HanPatch            hpatAB;
  2210.      HanPatch            hpatBA;
  2211.      HanEdge             hedgNext;
  2212.      } EdgeInfo;
  2213.  
  2214. hverA         Handle to the vertex at one endpoint
  2215.  
  2216. hverB         Handle to the vertex at the other endpoint
  2217.  
  2218. hpatAB        Handle to the patch which uses the edge
  2219.               from vertex A to vertex B. NULL_HANDLE if
  2220.               not used
  2221.  
  2222. hpatBA        Handle to the patch which uses the edge
  2223.               from vertex B to vertex A. NULL_HANDLE if
  2224.               not used
  2225.  
  2226. hedgNext      Handle to the next edge in this object
  2227.  
  2228. Comments
  2229.  
  2230. Contains information about a queried edge. Each edge
  2231. should be used twice if the object is fully enclosed by
  2232. patches. If the object isn't fully enclosed one of the
  2233. patch handles will be set to NULL_HANDLE. Since edges are
  2234. created and deleted automatically by the geometry engine
  2235. you will not receive an edge used by no patches as any
  2236. such edges would have been deleted.
  2237.  
  2238.  
  2239.  
  2240.  
  2241. typedef struct ObjectInfotag       // oi
  2242.      {
  2243.      ulong               ulNumVerts;
  2244.      ulong               ulNumNorms;
  2245.      ulong               ulNumPatches;
  2246.      ulong               ulNumEdges;
  2247.      float                    fNewVertTol;
  2248.      ulong               ulMemUsed;
  2249.      ushort              usCoorType;
  2250.      HanCoorSys          hcsys;
  2251.      HanVertex           hverFirst;
  2252.      HanNormal      hnorFirst;
  2253.      HanPatch            hpatFirst;
  2254.      HanEdge             hedgFirst;
  2255.      HanObject           hobjNext;
  2256.      } ObjectInfo;
  2257.  
  2258. ulNumVerts    Number of verticies defined in the object
  2259.  
  2260. ulNumNorms    Number of normals defined in the object
  2261.  
  2262. ulNumPatches  Number of patches defined in the object
  2263.  
  2264. ulNumEdges    Number of edges defined in the object
  2265.  
  2266. float         Indication of how close new verticies can
  2267.               be to neighbouring verticies without
  2268.               getting re-used
  2269.  
  2270. ulMemUsed     Total memory used by object and all its
  2271.               verticies, patches etc. (in bytes)
  2272.  
  2273. usCoorType    Type of coordinate system object belongs
  2274.               to;
  2275.  
  2276.  CT_LEFTHAND      Coordinate system is left handed
  2277.  
  2278.  CT_RIGHTHAND     Coordinate system is right handed
  2279.  
  2280. hcsys         Handle of the coordinate system this
  2281.               object belongs to
  2282.  
  2283. hverFirst     Handle to the first vertex in this object
  2284.  
  2285. hnorFirst     Handle to the first normal in this object
  2286.  
  2287. hpatFirst     Handle to the first patch in this object
  2288.  
  2289. hedgFirst     Handle to the first edge in this object
  2290.  
  2291. hobjNext      Handle to the next object in the
  2292.               coordiante system
  2293.  
  2294. Comments
  2295.  
  2296. Contains information about a queried object.
  2297.  
  2298.  
  2299.  
  2300.  
  2301. typedef struct CoorSysInfotag      // csi
  2302.      {
  2303.      ushort              usType;
  2304.      Mat                 matToParent;
  2305.      Mat                 matFromParent;
  2306.      HanCoorSys          hcsysParent;
  2307.      HanCoorSys          hcsysNext;
  2308.      HanCoorSys          hcsysFirstChild;
  2309.      HanLight            hliFirst;
  2310.      HanObject           hobjFirst;
  2311.      } CoorSysInfo;
  2312.  
  2313. usType             Type of coordinate system
  2314.  
  2315.  CT_LEFTHAND      Coordinate system is left handed
  2316.  
  2317.  CT_RIGHTHAND     Coordinate system is right handed
  2318.  
  2319. matToParent   Matrix describing the orientation of this
  2320.               coordinate system relative to the parent.
  2321.               The matrix will convert a point in our
  2322.               coordinate system into that of the parent.
  2323.  
  2324. matFromParent The inverse of matToParent. This matrix
  2325.               will convert a point in the parent
  2326.               coordinate system into ours.
  2327.  
  2328. hcsysParent   Handle to parent coordinate system
  2329.  
  2330. hcsysNext     Handle to next sibling coordinate system,
  2331.               ie. the next coordinate system which also
  2332.               has hcsysParent as its parent
  2333.  
  2334. hcsysFirstChild    Handle to the first of our child
  2335.               coordinate system, ie. the first
  2336.               coordinate system which has us as the
  2337.               parent (query this coordinate system to
  2338.               find the next one)
  2339.  
  2340. hliFirst           Handle to the first light in this
  2341.               coordinate system (query this light to
  2342.               find the next one)
  2343.  
  2344. hobjFirst     Handle to the first object in this
  2345.               coordinate system (query this object to
  2346.               find the next one)
  2347.  
  2348. Comments
  2349.  
  2350. Contains information about a queried coordinate system.
  2351.  
  2352.  
  2353.  
  2354.  
  2355. typedef struct LightDeftag         // ld
  2356.      {
  2357.      Vec                 vecPos;
  2358.      Vec                 vecDir;
  2359.      ushort              usFlags;
  2360.      float                    fInt;
  2361.      float                    fAng;
  2362.      Colour              col;
  2363.      HanLight            hliNext;
  2364.      } LightDef;
  2365.  
  2366. vecPos        3D position of light
  2367.  
  2368. vecDir        3D position towards which the light is
  2369.               directed
  2370.  
  2371. usFlags       Flags describing the light;
  2372.  
  2373.  LI_DIRECTIONAL   Light has a directional beam
  2374.  
  2375. fInt          Intensity of the light from 0 to 1
  2376.  
  2377. fAng          Angle of the lights beam (if directional)
  2378.  
  2379. col           Colour of the light
  2380.  
  2381. hliNext       Handle of the next light in this
  2382.               coordinate system
  2383.  
  2384. Comments
  2385.  
  2386. Contains information about a light. Can be used to set
  2387. the light or query the light. NB. The default Geometry
  2388. engine does not support directional or coloured lights.
  2389.  
  2390.  
  2391.  
  2392.  
  2393. typedef struct SurfTypetag         // st
  2394.      {
  2395.      Colour              col;
  2396.      ushort              usFlags;
  2397.      ushort              usSpecRefChar;
  2398.      float                    fShineCoef;
  2399.      float                    fTransCoef;
  2400.      HanCoorSys          hcsysTex;
  2401.      Mat                 matTex;
  2402.      HanSurf             hsurSurf0;
  2403.      HanSurf             hsurSurf1;
  2404.      HanSurf             hsurSurf2;
  2405.      HanSurf             hsurSurf3;
  2406.      float                    fBumpHeight;
  2407.      char                szFNTex[128];
  2408.      } SurfType;
  2409.  
  2410. col           Basic colour of the surface
  2411.  
  2412. usFlags       A set of bitwise OR'd flags defining the
  2413.               type of surface
  2414.  
  2415.  DS_TEXTURE       Surface is textured
  2416.  DS_RECURSIVE_TEXTURE  The texture is a recursive
  2417.                    texture. The default Geometry engine
  2418.                    does not support recursive textures.
  2419.  DS_TILE_TEXTURE  The texture will be tiled. If the
  2420.                    texture is not tiled the basic
  2421.                    surface colour `col' will show
  2422.                    through where the texture does not
  2423.                    reach, or where hsurSurf0-4 is set to
  2424.                    NULL_HANDLE for recursive textures.
  2425.  DS_BUMPED        The texture will be bump mapped. It
  2426.                    is not valid to have this on as well
  2427.                    as DS_RECURSIVE_TEXTURE. The default
  2428.                    Geometry engine does not support bump
  2429.                    mapped textures.
  2430.  
  2431. usSpecRefChar This value describes only how the specular
  2432.               highlights will appear on the surface. It
  2433.               does not mean that an SRC_GOLD surface
  2434.               will have a gold colour but given enough
  2435.               patches the positioning and size of the
  2436.               specular highlights will mimic a surface
  2437.               made of gold
  2438.  
  2439.               The following types are permitted;
  2440.  
  2441.                  SRC_DULL   (Surface has no specular
  2442.                              highlights)
  2443.                  SRC_CONSTANT    (50% reflection
  2444.                              regardless of incidence
  2445.                              angle)
  2446.                  SRC_LINEAR (Amount of reflected light
  2447.                              increases in proportion to
  2448.                              incidence angle)
  2449.                  SRC_SILVER (Produces large diffuse
  2450.                              highlights)
  2451.                  SRC_GOLD   (Produces dull ring shaped
  2452.                              highlights)
  2453.                  SRC_GLASS  (Produces highlights only on
  2454.                              the horizon edges of
  2455.                              objects)
  2456.                  SRC_BRASS  (The default Geometry engine
  2457.                              does not implement
  2458.                  SRC_COPPER any further ,but maps them
  2459.                              to the nearest of the
  2460.                  SRC_ALUMINIUM    above...)
  2461.                  SRC_IRON
  2462.                  SRC_PLASTIC
  2463.                  SRC_WATER
  2464.                  SRC_CHINA
  2465.                  SRC_LEATHER
  2466.                  SRC_SILK
  2467.  
  2468.               For completeness sake the following types
  2469.               are defined but mean the same as SRC_DULL
  2470.               as they are not shiny surfaces;
  2471.  
  2472.                  SRC_ROCK   (same as SRC_DULL...)
  2473.                  SRC_RUBBER
  2474.                  SRC_WOOD
  2475.                  SRC_FABRIC
  2476.  
  2477. fShineCoef    Shinyness coefficient. This values ranges
  2478.               from 1 to 10. Large values mean highly
  2479.               polished, and therefore very reflective
  2480.               surfaces. These generate very small but
  2481.               bright highlights with sharply defined
  2482.               edges (eg. a snooker ball). Small values
  2483.               produces large, dull, diffuse highlights
  2484.               (eg. a peice of paper)
  2485.  
  2486. fTransCoef    Transmissive coefficient. A value ranging
  2487.               from 0 to 1 to describe how transparent
  2488.               the surface is. A value of 1 would make
  2489.               the surface invisible. The default
  2490.               Geometry engine does not support
  2491.               transmissive surfaces
  2492.  
  2493. hcsysTex      The handle of the coordinate system the
  2494.               texture is defined relative to. See below
  2495.               for further details. NB. Because a texture
  2496.               is defined in one coordinate system,
  2497.               doesn't mean it cant be used by patches in
  2498.               another. Textures pervade all of 3D space,
  2499.               however because top level coordinate
  2500.               systems aren't related to each other by
  2501.               matricies like parent-child-sibling
  2502.               relationships, it does means that the
  2503.               orientation of a texture in one top level
  2504.               coordinate system or scene won't have any
  2505.               meaning in other and may come out looking
  2506.               confusing. However, the ModSurfType call
  2507.               can be used to modify the coordinate
  2508.               system a texture is defined in
  2509.  
  2510. matTex        The orientation of the texture bitmap
  2511.               within the coordinate system. When a
  2512.               texture is defined the bitmap is projected
  2513.               through 3D space and `rubs off' on any
  2514.               patch using this surface type. If you
  2515.               supply the identity matrix here then the
  2516.               orientation of the bitmap is such that the
  2517.               bottom left is at the origin of the
  2518.               coordinate system, and the bottom edge
  2519.               proceeds along the x axis for however many
  2520.               pixels wide the bitmap is, eg. If we have
  2521.               a 100 pixel wide bitmap the bottom left
  2522.               will be at 0, 0, 0 and the bottom right at
  2523.               100, 0, 0 in the coordinate system.
  2524.               Similarly the top of the bitmap proceeds
  2525.               up the y axis of the coordinate system.
  2526.               The bitmap is projected through the z axis
  2527.               to +/- infinity. By changing this matrix
  2528.               you can alter the plane of the bitmap or
  2529.               scale it to any size
  2530.  
  2531. hsurfSurf0-3  A recursive bitmap is one where the colour
  2532.               values in the bitmap refer not to colours
  2533.               in the bitmaps palette, but to other
  2534.               surfaces types which can in turn be
  2535.               textured, or even recursive textures. The
  2536.               surface handles for the colour values 0 to
  2537.               3 can be set here. A value of NULL_HANDLE
  2538.               means the surface's colour (defined by
  2539.               `col') shows through, whereas a value of
  2540.               HSUR_SEE_THROUGH means that the object has
  2541.               a hole in it at at those points showing
  2542.               objects that may be behind. The default
  2543.               Geometry engine does not support recursive
  2544.               textures
  2545.  
  2546. fBumpHeight   If the DS_BUMPED flag is set, the colour
  2547.               values in the bitmap refer to height
  2548.               values for a bumpy surface. The effective
  2549.               height of the maximum colour value is set
  2550.               using this parameter. The default Geometry
  2551.               engine does not support bump mapping
  2552.  
  2553. szFNTex       The full name (including path and
  2554.               extension) of a windows bitmap file to use
  2555.               as a texture
  2556.  
  2557. Comments
  2558.  
  2559. Defines a surface type. This structure can be used to
  2560. both set, query and modify a surface type.
  2561.  
  2562.  
  2563.  
  2564. Tool Interface
  2565.  
  2566. Introduction
  2567.  
  2568. Although custom tools are implemented as a C++ class, an
  2569. understanding of the C++ language is not essential as we
  2570. have supplied a template source file; toolexmp.cpp,
  2571. defining the class. All you need to do is to fill in the
  2572. functions which can be written in normal C language. The
  2573. source to the patch tool is also supplied as an example
  2574. (see patch.cpp). Only a basic understanding of
  2575. programming the windows operating system is required as
  2576. the only windows calls you are likely to make are the GDI
  2577. drawing calls such as, MoveTo and LineTo. Dialog box
  2578. calls will also be required if your tool needs a
  2579. configuration dialog box. An understanding of the
  2580. Geometry API is required.
  2581.  
  2582. The screen shot below is useful to refer to when reading
  2583. this section.
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593.  
  2594.  
  2595.  
  2596.  
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617. You will notice that some of the Geometry API functions
  2618. are also available through the tool interface and have
  2619. been slightly modified. This does not mean that you can't
  2620. use the original Geometry version.s There are two reasons
  2621. we have done this; Some functions, DefPatch for example
  2622. are built on top of Geometry's DefPatch and provide
  2623. additional functionality, for instance if an error occurs
  2624. during the DefPatch call (say `out of memory') the error
  2625. will be reported to the user in a message box and
  2626. everything created by the tool up to that point will be
  2627. erased. This is the sort of thing many tools would have
  2628. to implement, so to save time and effort the tool base
  2629. class DefPatch does it for you (if you want it to).
  2630.  
  2631. The other reason for duplicating some functions is that
  2632. the editor gives names to things like objects and
  2633. coordinates systems. Since Geometry only has the concept
  2634. of handles and not names, if your tool needs to create an
  2635. object called `MyBox' it needs to call the editor version
  2636. of AddObject for the name to appear in the list box on
  2637. the control bar. If you use the Geometry version it will
  2638. still be visible and will be rendered, but without a name
  2639. it wont be selectable at a single mouse click from the
  2640. listbox and any tools that require the name of an object
  2641. to modify will not be able to process the object.
  2642.  
  2643.  
  2644. Writing custom tools
  2645.  
  2646. Each tool is implemented in a windows DLL by writing a
  2647. C++ class derived from the base tool class; `Tool'. The
  2648. base class is implemented in tool.dll. Your derived class
  2649. should include tool.h and should be linked to tool.lib.
  2650.  
  2651. Your DLL should include a resource file defining a 16
  2652. pixel wide by 15 pixel high bitmap with a resource ID of
  2653. one. This bitmap contains an image which will
  2654. automatically be placed on a button in the toolbox to
  2655. enable your tool to be invoked. If you are using
  2656. Microsoft App Studio this can be done by entering; <id>=1
  2657. in the id field of the properties dialog for the bitmap.
  2658.  
  2659. The tool object
  2660.  
  2661. The DLL should provide a routine to create and delete an
  2662. object belonging to your tool class which will be called
  2663. by the editor. The IMPLEMENT_OBJECT macro will do this
  2664. for you. The following line must be added to your main
  2665. source file;
  2666.  
  2667.      IMPLEMENT_OBJECT(<your_class_name>)
  2668.  
  2669. You must also add the following to the exports section of
  2670. your .def file;
  2671.  
  2672.      _CREATETOOL
  2673.      _DELETETOOL
  2674.  
  2675. The editor will create one of your tool objects for each
  2676. scene that exists. Note, this is not the same as the
  2677. view. You can have several views into a single scene. It
  2678. works in the same in same way that a word processor can
  2679. have several documents loaded at once, and you might have
  2680. several windows showing different parts of the same
  2681. document. The reason for this is that it makes tool
  2682. writing considerably simpler as a tool can be
  2683. constructing in different scenes at once without the tool
  2684. code having to manage a complete set of varaibles
  2685. relating to each scene. Therefore a tool defines just one
  2686. set of member variables that it needs to do its job.
  2687.  
  2688. The tool's configuration dialog box
  2689.  
  2690. If your tool defines a configuration dialog box, you
  2691. generally want the dialog to apply to all tools belonging
  2692. to your object. For instance when editing in scene A, you
  2693. configure your tool in a certain way. You then switch to
  2694. scene B, since you see only one tool of your type in the
  2695. toolbox, you assumes it is configured the way you just
  2696. set it. Now, if your configuration data is stored as
  2697. member variables within  your object there will be a
  2698. separate configuration for each tool, ie one for each
  2699. scene. So generally it is best to make your configuration
  2700. variables static members or global.
  2701.  
  2702. How to tell the editor about your tool
  2703.  
  2704. The name of your DLL should be added to the Gened.ini
  2705. file in the main windows directory, under the section
  2706. [Tools] as follows;
  2707.  
  2708.                [Tools]
  2709.                0=patch
  2710.                1=sphere
  2711.                2=box
  2712.                :
  2713.                n=<name of your DLL>
  2714.  
  2715. The value of n must be the next unused consequective
  2716. number.
  2717.  
  2718. Overriding tool functions
  2719.  
  2720. Whenever the `Set' or `Do' buttons on the control bar is
  2721. pressed, or the `Undo' menu item is selected an
  2722. appropriate function is called in the currently selected
  2723. tool. The tool base class provide default functions which
  2724. actually do nothing. To detect these events you can
  2725. override these functions in your derived class. The
  2726. following table shows the events which trigger tool
  2727. functions;
  2728.  
  2729. Event      Called when
  2730. OnSelect   The tool has been selected from the
  2731.            toolbox
  2732. OnUnSelec  An attempt has been made to select
  2733. t          another tool
  2734. OnButtonD  The mouse is in the view and the left
  2735. own        button is pressed
  2736. OnMouseMo  The left button is pressed and the
  2737. ve         mouse moves
  2738. OnButtonU  The left mouse button is released
  2739. p
  2740. OnSet      The `Set' button on the control bar
  2741.            is pressed
  2742. OnDo       The `Do' button on the control bar is
  2743.            pressed
  2744. OnViewCha  The active view into the scene has
  2745. nge        changed
  2746. OnUndo     The `Undo' menu item is selected and
  2747.            this was the last active tool
  2748. OnConfigu  The user requests to configure the
  2749. re         tool
  2750.  
  2751. Calling sequence
  2752.  
  2753. The very first call to all tools is Initialise. Overide
  2754. it if you need to initialise any variables. The next
  2755. likely call to your tool will be when it is selected from
  2756. the toolbox, the OnSelect routine will be invoked. Then
  2757. as the user user clicks and moves the mouse in the view
  2758. you will receive OnButtonDown, OnMouseMove and OnButtonUp
  2759. events. Then when the user presses the `Set' button,
  2760. having positioned the 3D cursor, the OnSet call is
  2761. invoked. This can be invoked as many times as your tool
  2762. requires. If your tool requires an indefinite number of
  2763. Set presses, then the `Do' button can be used to do
  2764. whatever is required to complete the tools action. For
  2765. instance, the patch tool uses Set to position each
  2766. vertex. Since you can define an indefinite number of
  2767. verticies, the Do button is used to create the patch. The
  2768. interpretation of the buttons is entirely up to you.
  2769.  
  2770. All events are directed to the currently selected tool
  2771. only, apart from, obviously OnSelect, and OnUndo.
  2772.  
  2773. Modifying and undoing
  2774.  
  2775. For your custom tool to be seamlessly integrated with the
  2776. editor, it must be capable of undoing any action it has
  2777. performed on the object. If and when a tool modifies any
  2778. aspect of a scene, wether its creating or deleting part
  2779. of an object, moving a light or even changing the colour
  2780. of a patch it must call the `ModifiedScene' function.
  2781. This has two effects. First of all it marks the scene as
  2782. having changed and will give the user a warning if he
  2783. tries to close the editor down without having saved the
  2784. scene first. Secondly it marks this tool for calling
  2785. should the user select the `Undo' menu item. This tool
  2786. can now be called to undo its action even after it has
  2787. been de-selected, at least until another tool calls the
  2788. ModifiedScene routine.
  2789.  
  2790. Drawing into the view
  2791.  
  2792. During the construction of a primitive the tool will
  2793. probably need to draw into the views showing the object
  2794. being constructed, to give the user some feedback about
  2795. what is going on. There are two ways of doing this. The
  2796. tool can implement the DrawSoFar routine so that whenever
  2797. the view gets updated it gets a chance to draw into the
  2798. DC representing the view window. The patch tool draws a
  2799. dotted line between the cursor positions at each point
  2800. Set was pressed using this technique. The patch isn't
  2801. actually created on Geometry until the Do button is
  2802. pressed. Alternatively, more complex tools might
  2803. construct the object on Geometry in several steps (eg.
  2804. during Set presses, or on mouse move events) in which
  2805. case the editor can redraw it for you. The sphere tool
  2806. does this. A combination of these techniques can also be
  2807. used.
  2808.  
  2809. When the screen view needs repainting, say if part of it
  2810. is uncovered by a window on top, the editor redraws the
  2811. rendered image along with its wire frame and then calls
  2812. the selected tool's DrawSoFar routine passing it the
  2813. device context handle of the view window. The DrawSoFar
  2814. routine will be called for each view into the object
  2815. which needs updating. If we attempt to draw into the view
  2816. on any call other than a DrawSoFar, then we have to
  2817. consider the fact that there might be several views into
  2818. this object all of which will need updating. For this
  2819. reason drawing should be reserved exclusively for the
  2820. DrawSoFar routine.
  2821.  
  2822. The view will probably need updating after a Set/Do press
  2823. or an Undo selection. Although we cannot draw on these
  2824. event we can return a value which will cause the view to
  2825. be repainted, and therefore DrawSoFar to be called.
  2826.  
  2827. Drawing return codes
  2828.  
  2829. For each view into the scene the editor maintains two
  2830. bitmaps. The first is the full colour rendered bitmap
  2831. generated by Geometry's Render call. The second is a
  2832. monochrome overlay containing the image of the x, y, and
  2833. z axis, the objects wire frame, and optionally a set of
  2834. grid points. When the object changes all this needs to be
  2835. updated; the image must be re-rendered and the overlay
  2836. regenerated. When a tool is in a constructing state, we
  2837. might want to draw the object quickly. For instance the
  2838. sphere or box tool might require the radius or corner to
  2839. be dragged by the mouse and released when you release the
  2840. button. Given that there could be several views into the
  2841. object there is not time to re-render and regenerate the
  2842. overlay for every view as the mouse moves. The whole
  2843. thing would be too slow. The following return codes from
  2844. event functions can tell the editor how to redraw
  2845. quickly.
  2846.  
  2847. REDRAW_ALL
  2848.  
  2849. This is typically used only once when the tool has
  2850. finished its business and tells the editor to re-render
  2851. the main bitmaps and regenerate all overlays for each
  2852. view. The screen image for each view is then refreshed
  2853. from both of these. This takes the most amount of time
  2854. and so it is highly unlikely you will ever want to use
  2855. this from a mouse move event.
  2856.  
  2857. The current tools DrawSoFar routine will also be.
  2858.  
  2859. REDRAW_NONE
  2860.  
  2861. Pretty much self explanitory. This return code will not
  2862. affect the on screen image in any way.
  2863.  
  2864. REDRAW_OBJECT_WIRE
  2865.  
  2866. This causes the editor to draw the wire frame of the last
  2867. object created by the tool base class's AddObject
  2868. function directly onto the screen using the GDI XOR mode.
  2869. The XOR mode has the effect that if you draw something
  2870. into a DC twice, it actually removes it leaving you with
  2871. the original image. Using this return code does not cause
  2872. the screen image to get refreshed from the rendered and
  2873. overlay bitmaps, so it is very fast. The box creation
  2874. tool might use this return code to update the wire frame
  2875. of the box on the mouse move event when dragging a corner
  2876. to get the correct box size (see the `Dragging with the
  2877. mouse' section).
  2878.  
  2879. Again the current tools DrawSoFar routine is called.
  2880.  
  2881. REDRAW_TOOL
  2882.  
  2883. The REDRAW_ALL and REDRAW_OBJECT_WIRE return codes result
  2884. in the editor redrawing the object as it exists within
  2885. Geometry (ie. as seen through Geometry's query
  2886. functions). If the object within Geometry hasn't changed,
  2887. returning these codes will be wastefull as the on screen
  2888. image wont change. Instead the REDRAW_TOOL return code
  2889. results in just the tools DrawSoFar routine being called.
  2890. The patch tool uses this after setting a vertex.
  2891.  
  2892. REDRAW_NOTOOL
  2893.  
  2894. This causes the editor to simply refresh the screen from
  2895. its internal bitmaps, thereby effectively removing any
  2896. image drawn as a result of a DRAW_OBJECT_WIRE code, or
  2897. anything drawn by a tool's DrawSoFar routine. If a tool
  2898. has used either of these to draw an object during a
  2899. construction phase but undo was selected before the
  2900. operation completed, then this return code can be used to
  2901. erase the `construction image' on the screen. If we
  2902. actually constructed parts of an object on Geometry then
  2903. we must remember to remove them as well otherwise the
  2904. next time a render is performed the object will reappear!
  2905.  
  2906. The DrawSoFar routine is not called as a result.
  2907.  
  2908.  
  2909. REDRAW_REFRESH
  2910.  
  2911. This is the same as a REDRAW_NOTOOL except that the
  2912. tool's DrawSoFar routine is called as well.
  2913.  
  2914. Getting 2D screen coordinates
  2915.  
  2916. The actual drawing is done using the windows GDI. The 2D
  2917. window coordinates you need to perform the drawing
  2918. operations can be got using Geometry calls such as
  2919. Get3DPoint and Get3DLine. The Geometry API spec states
  2920. that before you can use these calls you must set the
  2921. camera in the appropriate coordinate system. Obviously
  2922. without specifying a camera view the 3D coordinate you
  2923. work with will not have a 2D counterpart. Before
  2924. DrawSoFar is called the editor sets the camera at the
  2925. viewpoint in the coordinate system of the view being
  2926. redrawn so the tool doesn't have to worry about this. On
  2927. event calls like OnSet and OnMouseMove the camera is set
  2928. in the currently active view, ie. the one that has the
  2929. focus.
  2930.  
  2931.  
  2932.  
  2933. Dragging with the mouse
  2934.  
  2935. The sphere tool creates a small sphere when Set is
  2936. pressed, if the `quickdraw' configuration option is
  2937. switched off. It then traps the OnMouseMove event and
  2938. scales the sphere to the correct radius. By returning
  2939. REDRAW_OBJECT_WIRE it gets the editor to draw the wire
  2940. frame of the sphere.
  2941.  
  2942. If it is more appropriate to perform drawing ourself then
  2943. simply use GDI's ROP2 setting of XORPEN to draw and erase
  2944. your image in the DrawSoFar routine. You may of course
  2945. prefer to save the background before drawing on it, but
  2946. in general we have found that XOR drawing is faster. The
  2947. only thing to remember is that if you change any of the
  2948. DC's attributes such as selected pen, drawing mode etc.
  2949. you must set them back to the originals before DrawSoFar
  2950. returns. NB. This is a general requirement of programming
  2951. in Windows.
  2952.  
  2953. XOR'ing in multiple views
  2954.  
  2955. If you wish to implement dragging on the mouse move event
  2956. as described above there is just one other thing to bear
  2957. in mind. Consider the following sequence of events.
  2958. Assume that this is part of a cube construction tool. We
  2959. `Set' the cursor at one corner then move the cursor to
  2960. the opposite corner (during which the box is being
  2961. dynamically sized in the view[s]), and press `Do'.
  2962. Further assume we have two views into this scene.
  2963.  
  2964.      1.   OnSet event - Set the 3D coordinates of the first
  2965.        corner to those of the cursor. Set the 3D coordinates of
  2966.        the far corner to the same as the first and return
  2967.        REDRAW_TOOL to start the XOR drawing (initially a point
  2968.        sized cube as both corners are in the same place)
  2969.      2.   OnDrawSoFar call - Called for the first view as a
  2970.        result of returning REDRAW_TOOL from OnSet. Being the
  2971.        first DrawSoFar for this view there is no previous
  2972.        construction image to remove, so simply draw the image in
  2973.        XOR mode (ie. a cube) using Get3DPoint to convert your 3D
  2974.        corners into 2D window coordinates and draw them using
  2975.        the GDI. Store the 2D coordinates of your construction
  2976.        image so you can erase it later
  2977.      3.   OnDrawSoFar call - Called for the second view. Do
  2978.        exactly the same as for the previous DrawSoFar but for
  2979.        the second view
  2980. 4.   OnMouseMove event - Set the 3D coordinates of the
  2981. opposite corner to the cursor position, and return
  2982. REDRAW_TOOL
  2983.      5.   OnDrawSoFar call - Called for the first view as a
  2984.        result of returning REDRAW_TOOL from the OnMouseMove
  2985.        event. Redraw the old construction image in XOR mode to
  2986.        erase the image and redraw the image in XOR mode using
  2987.        the opposite corner in its new position
  2988.      6.   OnDrawSoFar call - Called for the second view. Do
  2989.        exactly the same as for the previous DrawSoFar but for
  2990.        the second view
  2991.      7.   Do steps 4, 5 and 6 - For however many mouse move
  2992.        events we get
  2993.      8.   OnDo event - Construct the cube using Geometry and
  2994.        return REDRAW_ALL to get it rendered properly
  2995.  
  2996. You will notice that because we have two views we get two
  2997. DrawSoFar calls every time we return REDRAW_TOOL from an
  2998. event. This means that we must store two sets of
  2999. coordinates in order to removethe previous XOR image. For
  3000. this purpose DrawSoFar gets called with a parameter to
  3001. instance data relating to each particular view.
  3002.  
  3003. DrawSoFar parameters
  3004.  
  3005. The first parameter contains the DC handle of the view.
  3006. You need this when using GDI drawing commands.
  3007.  
  3008. The second parameter is a pointer to a 60 byte area of
  3009. memory stored as part of each view known as the view
  3010. instance data. You can use this memory to store whatever
  3011. you like, eg. coordinates of the construction image. If
  3012. you need more memory than this you can allocate your own
  3013. and store a pointer to the memory in the view instance
  3014. data. The SetViewData call in the tool base class can be
  3015. used to intialise the instance data at any time (say,
  3016. from the OnSet event).
  3017.  
  3018. The final parameter is a boolean value which says why
  3019. this routine has been called. Not only will you receive a
  3020. DrawSoFar call as the result of returning REDRAW_TOOL
  3021. from an event but you will also receive one if part of
  3022. the view was invalidated by a window on top of the view
  3023. being removed. In normal windows programming this will
  3024. generate a WM_PAINT message. If this happens and your
  3025. tool is in the process of constructing an XOR image it
  3026. must not erase the previous image because the view is
  3027. invalid in that region. As a general rule, if this
  3028. bInvalid parameter is TRUE simply draw the XOR image as
  3029. if it were the first OnDrawSoFar for this view.
  3030.  
  3031. General guidelines
  3032.  
  3033. Help on using tools
  3034.  
  3035. As a general rule any tool should provide instructions to
  3036. the user on how to operate the tool. The recommended
  3037. approach is at each stage inform the user what to do next
  3038. by writing a message in the status bar at the bottom of
  3039. the main window using the WriteMessage function. See the
  3040. Sphere or Patch tools as an example.
  3041.  
  3042. Displaying text strings
  3043.  
  3044. Whenever your tool displays any text it is a good idea to
  3045. load the text from a string table resource. This way if
  3046. your tool ever gets used in other countries, language
  3047. translation is a simple matter of going through the
  3048. string table and recompiling to get a new DLL, rather
  3049. than having to search through the source code for literal
  3050. strings. The tool base class functions such as
  3051. WriteMessage and MessageBox aid this by allowing you to
  3052. present string resource ids as well as character
  3053. pointers.
  3054.  
  3055.  
  3056. Coordinate system types
  3057.  
  3058. Any tool which creates patches has to consider the fact
  3059. it could be invoked in either a lefthand or a righthand
  3060. coordinate system. The significance is in the ordering of
  3061. the verticies. Remember verticies should always be seen
  3062. to progress clockwise around the patch. If your tool
  3063. works fine in one system but not in the other then you
  3064. probably need to reverse the ordering in the system which
  3065. doesn't work.
  3066.  
  3067.  
  3068.  
  3069. A note for C Users
  3070.  
  3071. For those not familiar with C++, you can use the
  3072. toolexmp.cpp file as a base to work from. The functions
  3073. defined in the `Overridables' section are functions you
  3074. can implement yourself if you're interested in trapping
  3075. those particular events. Empty functions are defined but
  3076. commented out in toolexmp.cpp. If you want to trap mouse
  3077. moves events simply uncomment it and add your code using
  3078. normal C. Remember C++ is a superset of the C language.
  3079.  
  3080. The functions defined in the section titled `Support' are
  3081. supplied for you to call should the need arise. One thing
  3082. you will realise about C++ is that a function is
  3083. specified not just by its name but also by its paramters,
  3084. meaning you can have two or more functions with the same
  3085. name as long as they have differents paramters (NB. The
  3086. MessageBox support function is an example).
  3087.  
  3088. Some variables are also defined in the `Support' section.
  3089. In C++ terminology these are protected variables defined
  3090. in the base class. Non C++ programmers can just think of
  3091. them as global variables containing information which may
  3092. or may not be of use to your tool. You must not attempt
  3093. to alter these vaiables.
  3094.  
  3095.  
  3096.  
  3097. Overridables
  3098.  
  3099.  
  3100. virtual ~Tool();
  3101.  
  3102. Comments
  3103.  
  3104. Destructor for your tool object. This function must be
  3105. overidden even if it does nothing. As with any normal C++
  3106. class, if you create a constructor for your object which
  3107. allocates resources, the destructor must release these
  3108. resources. C users can leave this function empty.
  3109.  
  3110.  
  3111.  
  3112.  
  3113. virtual void Initialise();
  3114.  
  3115. Comments
  3116.  
  3117. Called once when the DLL is loaded. This call can be used
  3118. to initialise variables.
  3119.  
  3120.  
  3121.  
  3122.  
  3123. virtual Redraw OnSelect(Vec &vec);
  3124.  
  3125. vec            Current psition of the 3D cursor.
  3126.  
  3127. Comments
  3128.  
  3129. Called when the user selects the tool from the toolbox.
  3130.  
  3131.  
  3132.  
  3133.  
  3134. virtual Redraw OnUnSelect(bool *pbOkToChange)
  3135.  
  3136. pbOkToChange   Set this to TRUE if it is OK for the
  3137. editor to change the current tool.
  3138.  
  3139. Comments
  3140.  
  3141. Called when the user tries to select another tool from
  3142. the toolbox. If the tool is in the middle of a
  3143. complicated operation it can either set *pbOkToChange to
  3144. FALSE or it can either abort its operation or complete it
  3145. without further action from the user. What happens here
  3146. is up to the tool writer. Remember the tool can always
  3147. undo what its just done if the user isn't happy.
  3148.  
  3149.  
  3150.  
  3151.  
  3152. virtual void OnConfigure();
  3153.  
  3154. Comments
  3155.  
  3156. Called when the tool is selected and the user then
  3157. selects the Configure item from the Tool menu. Typically
  3158. this call is overrided to construct a dialog box enabling
  3159. the user to enter configuration information for the tool.
  3160.  
  3161.  
  3162.  
  3163.  
  3164. virtual Redraw OnButtonDown(Vec &vec);
  3165.  
  3166. vec            Current psition of the 3D cursor.
  3167.  
  3168. Comments
  3169.  
  3170. Called when the tool is selected and the user presses the
  3171. left mouse button when the mouse is in a view allowing
  3172. the 3D cursor to be moved. The vec parameter gives the
  3173. coordinates of the 3D cursor. The editor assumes the tool
  3174. is in a constructing state only after the first Set
  3175. press, so if you overide this function, construction
  3176. should not start until Set has been pressed. The Redraw
  3177. return code can be used to tell the editor how to
  3178. efficiently redraw the view.
  3179.  
  3180.  
  3181.  
  3182.  
  3183. virtual Redraw OnMouseMove(Vec &vec);
  3184.  
  3185. vec            Current psition of the 3D cursor.
  3186.  
  3187. Comments
  3188.  
  3189. Called when the 3D cursor moves within a view. NB.
  3190. Windows programmers should realise that this is not quite
  3191. the same as a WM_MOUSEMOVE message as the left button has
  3192. to be depressed while the mouse is over a view.
  3193.  
  3194.  
  3195.  
  3196.  
  3197. virtual Redraw OnButtonUp(Vec &vec);
  3198.  
  3199. vec            Current psition of the 3D cursor.
  3200.  
  3201. Comments
  3202.  
  3203. Called when the tool is selected and the user releases
  3204. the left mouse button when the mouse is in a view.
  3205.  
  3206.  
  3207.  
  3208.  
  3209. virtual Redraw OnSet(Vec &vec);
  3210.  
  3211. vec            Current psition of the 3D cursor.
  3212.  
  3213. Comments
  3214.  
  3215. Called when the 'Set' button is clicked after a tool has
  3216. been selected.
  3217.  
  3218.  
  3219.  
  3220.  
  3221. virtual Redraw OnUndo();
  3222.  
  3223. Comments
  3224.  
  3225. Called when user wishes to undo effect of tool. This can
  3226. be called even if the tool is not selected. If the
  3227. currently selected tool is not in a constructing state
  3228. and the user selects `Undo' from the `Edit' menu, then
  3229. the last tool to modify the object data is called.
  3230.  
  3231.  
  3232.  
  3233.  
  3234. virtual Redraw OnDo(Vec &vec);
  3235.  
  3236. vec            Current psition of the 3D cursor.
  3237.  
  3238. Comments
  3239.  
  3240. Called when the user presses the `Do' button on the
  3241. control bar. Typically this is used to end use of the
  3242. selected tool.
  3243.  
  3244.  
  3245.  
  3246.  
  3247. virtual void OnViewChange(HanCoorSys hcsys, Vec &vec);
  3248.  
  3249. hcsys               The coordinate system of the new
  3250. active view.
  3251.  
  3252. vec            Current psition of the 3D cursor.
  3253.  
  3254. Comments
  3255.  
  3256. Called when the user clicks the mouse in a new view
  3257. making it active. Since there is a separate object of
  3258. each tool type for each scene the tool will not be
  3259. notified of a view change into a different scene. In fact
  3260. the new active scene could have a different tool type
  3261. currently selected.
  3262.  
  3263. This event is also called if a tool calls the base class
  3264. version of AddCoorSys with the bAddView parameter set to
  3265. TRUE. In this case the OnViewChange event is called
  3266. before the AddCoorSys call returns.
  3267.  
  3268. virtual void DrawSoFar(HDC hdc,
  3269.                      HanCoorSys hcsys,
  3270.                      void *pvViewData,
  3271.                      bool bInvalid);
  3272.  
  3273. hdc            A handle to the device context of the view
  3274. being redrawn.
  3275.  
  3276. hcsys               Coordinate system handle of the view
  3277. being redrawn.
  3278.  
  3279. pvViewData          Pointer to instance data for the
  3280. view.
  3281.  
  3282. bInvalid      The region being redrawn was invalidated,
  3283.               probably by a window on top being removed.
  3284.  
  3285. Comments
  3286.  
  3287. Called when the view is being redrawn to give the tool a
  3288. chance to draw the `object so far' into the view.
  3289.  
  3290.  
  3291.  
  3292. Support
  3293.  
  3294.  
  3295. Protected member variables
  3296.  
  3297. hinst               Instance handle of the tool DLL.
  3298.  
  3299. hwnd           Handle to the main frame window.
  3300.  
  3301. ahverPrim     Array of handles to verticies created
  3302.               (ulNumVerts contains how many). See
  3303.               StartPrim for details.
  3304.  
  3305. hverPrim       Last handle created by an AddVertex call.
  3306.  
  3307. ulNumVerts          Number of vertex handles in
  3308. ahverPrim.
  3309.  
  3310. ahnorPrim     Array of handles to normals created
  3311.               (ulNumNorms contains how many). See
  3312.               StartPrim for details.
  3313.  
  3314. hnorPrim       Last handle created by an AddNormal call.
  3315.  
  3316. ulNumNorms          Number of normal handles in
  3317. ahnorPrim.
  3318.  
  3319. ahpatPrim      Array of handles to patches created
  3320. (ulNumPats contains how many).
  3321.  
  3322. ulNumPats      Number of patch handles in ahpatPrim.
  3323.  
  3324. hcsysTopLevel  Handle of top level coordinate system in
  3325. this scene.
  3326.  
  3327.  
  3328.  
  3329.  
  3330. void WriteMessage(int iResId);
  3331. void WriteMessage(const char *szMsg);
  3332.  
  3333. iResId              The resource id of the string within
  3334. the DLLs resource file.
  3335.  
  3336. szMsg               Pointer to a null terminated string.
  3337.  
  3338. Comments
  3339.  
  3340. Called to write a message in status bar at the bottom of
  3341. the main window.
  3342.  
  3343.  
  3344.  
  3345.  
  3346. int MessageBox(int iTitleId, int iMsgId,
  3347.               UINT uiStyle =MB_ICONEXCLAMATION);
  3348. int MessageBox(int iTitleId, char *szMsg,
  3349.               UINT uiStyle =MB_ICONEXCLAMATION);
  3350. int MessageBox(int iTitleId, GeomErr gerr);
  3351.  
  3352. iTitleId       The resource id of a string to use for the
  3353. message box title.
  3354.  
  3355. iMsgId              The resource id of the main message
  3356. string.
  3357.  
  3358. szMsg               A pointer to the message string.
  3359.  
  3360. gerr          A Geometry error value. The routine will
  3361.               query an appropriate error string from
  3362.               Geometry, and will use the
  3363.               MB_ICONEXCLAMATION style.
  3364.  
  3365. uiStyle       One of windows MB_ values to indicate the
  3366.               type of message box. This defaults to
  3367.               MB_ICONEXCLAMATION if omitted.
  3368.  
  3369. Comments
  3370.  
  3371. Puts a message box on the screen. There are three
  3372. variations on this function. If a tool gets an internal
  3373. processing error return code from Geometry it should use
  3374. the third form to notify the user, and then abort
  3375. whatever action it was performing.
  3376.  
  3377. The return code is the same as for the windows MessgeBox
  3378. function.
  3379.  
  3380.  
  3381.  
  3382.  
  3383. bool StartPrim (HanObject hobj,
  3384.              ulong ulMaxVerts,
  3385.              ulong ulMaxNorms,
  3386.              ulong ulMaxPats,
  3387.              bool bReportErrs,
  3388.              bool bUndoOnErr);
  3389.  
  3390. hobj           Handle to the object we want to add to.
  3391.  
  3392. ulMaxVerts          Maximum number of verticies we will
  3393. be adding.
  3394.  
  3395. ulMaxNorms          Maximum number of normals we will be
  3396. adding.
  3397.  
  3398. ulMaxPats      Maximum number of patches we will be
  3399. adding.
  3400.  
  3401. bReportErrs   If this is set to TRUE any Geometry errors
  3402.               that occur during AddVertex, AddNormal, or
  3403.               DefPatch (eg. `out of memory' or
  3404.               `verticies not on a plane') will be
  3405.               reported to the user in an message box.
  3406.  
  3407. bUndoOnErr    If this is set to TRUE and a Geometry
  3408.               error occurs then every patch, vertex and
  3409.               normal added to the object since the
  3410.               StartPrim call will be removed.
  3411.  
  3412. Comments
  3413.  
  3414. This routine can be used along with the, AddVertex,
  3415. AddNormal and DefPatch routines to add elements to an
  3416. object. They are usually more convenient than Geometry's
  3417. version of these functions because the handles to the
  3418. elements are automatically stored in arrays allocated by
  3419. this routine. For instance a tool will usually want to
  3420. access say the handle for the 8th vertex that it created.
  3421. If we use the base class version of the AddVertex
  3422. function we can access this handle using the ahverPrim
  3423. protected member variable of the tool base class, ie.
  3424. ahverPrim[7] for the 8th vertex. Similaraly ahnorPrim[7]
  3425. will access the 8th normal created and ahpatPrim[7] will
  3426. give you the 8th patch. What is more, if we need to undo,
  3427. the RemovePrim function will remove all the elements
  3428. created so far.
  3429.  
  3430. Once the tool has finished constructing and we have no
  3431. further interest in the handles, we must call the EndPrim
  3432. function to release the handle arrays. If during any
  3433. `Add' function a serious error is returned by Geometry a
  3434. description of the error can be automatically reported to
  3435. the user and the RemovePrim function called to remove all
  3436. elements created. The return code is then passed back to
  3437. the tool. In this case you must not call EndPrim.
  3438.  
  3439. If the tool has any reason to call RemovePrim itself it
  3440. should not call EndPrim as the RemovePrim routine does
  3441. this for you.
  3442.  
  3443. If you call say AddVertex to create more verticies than
  3444. you originally specified on the StartPrim call the
  3445. function will not fail, but the handle will not be stored
  3446. either, therefore if you call RemovePrim you might find
  3447. it doesn't remove all of your object.
  3448.  
  3449. StartPrim can be called with an object already containing
  3450. vertices, patches and normals.
  3451.  
  3452. This routine returns TRUE if it succeeded.
  3453.  
  3454.  
  3455.  
  3456.  
  3457. void EndPrim ();
  3458.  
  3459. Comments
  3460.  
  3461. Called after a StartPrim and when the tool has no further
  3462. need for handles to the elements its created. This
  3463. routine removes the buffers allocated by StartPrim.
  3464.  
  3465.  
  3466.  
  3467.  
  3468. void RemovePrim ();
  3469.  
  3470. Comments
  3471.  
  3472. Removes all primitive elements (verts, normals and
  3473. patches) added to the object the tool is working on.
  3474. Should be called only if a StartPrim has been called.
  3475.  
  3476. GeomErr AddVertex (Vec &vec);
  3477.  
  3478. vec            Position of vertex.
  3479.  
  3480. Comments
  3481.  
  3482. Adds a vertex  to the object specified by a call to
  3483. StartPrim and records its handle in the ahverPrim array.
  3484. The hver variable can be used as a more convenient way of
  3485. accessing the last handle created by an AddVertex call.
  3486.  
  3487. If Geometry reports an error this is passed to the user
  3488. in a message box.
  3489.  
  3490. This call can only be used after a call to StartPrim. See
  3491. StartPrim comment and Geometry's AddVertex function for a
  3492. full description.
  3493.  
  3494.  
  3495.  
  3496.  
  3497. GeomErr AddNormal (Vec &vec);
  3498.  
  3499.  
  3500. vec            Direction of normal.
  3501.  
  3502. Comments
  3503.  
  3504. Adds a normal  to the object specified by a call to
  3505. StartPrim and records its handle in the ahnorPrim array.
  3506. The hnor variable can be used as a more convenient way of
  3507. accessing the last handle created by an AddNormal call.
  3508.  
  3509. If Geometry reports an error this is passed to the user
  3510. in a message box.
  3511.  
  3512. This call can only be used after a call to StartPrim. See
  3513. StartPrim comment and Geometry's AddNormal function for a
  3514. full description.
  3515.  
  3516.  
  3517.  
  3518.  
  3519. GeomErr DefPatch (ushort usNumEdges,
  3520.                  ushort usFlags,
  3521.                  float fSmoothAng,
  3522.                  HanVertex *ahver,
  3523.                  HanNormal *ahnor,
  3524.                  HanSurf hsur);
  3525.  
  3526. usNumEdges    The number of edges, and therefore
  3527.               verticies and normals in the patch. This
  3528.               can be any number from 3 upwards.
  3529.  
  3530. usFlags       Flags controlling the creation of the
  3531.               patch.
  3532.  
  3533.  fSmoothAng   Specifies the angle to use for
  3534.               autosmoothing. Only takes effect if
  3535.               DP_SMOOTH_BY_ANGLE flag is used.
  3536.  
  3537. ahver         Array of handles to verticies. The number
  3538.               of verticies is given by the usNumEdges
  3539.               paramter.
  3540.  
  3541. ahnor         Array of handles to normals. The number of
  3542.               verticies is given by the usNumEdges
  3543.               paramter.
  3544.  
  3545. hsur          Handle to the surface type to be used for
  3546.               the patch. If you use NULL_HANDLE here
  3547.               then the currently selected surface type
  3548.               will be used. If no surface type has been
  3549.               selected then any available type will be
  3550.               used. If no surface types exists then one
  3551.               will be created.
  3552.  
  3553. Comments
  3554.  
  3555. Adds a patch to the object specified by a call to
  3556. StartPrim and records its handle in the ahpatPrim array.
  3557. Unlike AddVertex and AddNormal you cannot access the last
  3558. handle created using a protected base class variable as a
  3559. call to AddPatch can result in several patches being
  3560. created.
  3561.  
  3562. If Geometry reports an error this is passed to the user
  3563. in a message box.
  3564.  
  3565. This call can only be used after a call to StartPrim. See
  3566. StartPrim comment and Geometry's DefPatch function for a
  3567. full description.
  3568.  
  3569.  
  3570.  
  3571.  
  3572. HanObject AddObject(HanCoorSys hcsys,
  3573.                     char *szName,
  3574.                     ushort usBuffSize,
  3575.                     float fNewVertTol,
  3576.                     HanObject hobj)
  3577.  
  3578. hcsys         Handle to coordinate system to add object
  3579.               too.
  3580.  
  3581. szName        The name of the object to appear in the
  3582.               object list box. The actual name used is
  3583.               returned in this buffer as the name
  3584.               supplied might already be in use. If this
  3585.               is the case a number is added to the end
  3586.               of the name.
  3587.  
  3588. usBuffSize    Size of the szName buffer. To ensure that
  3589.               the modified name will fit you can set
  3590.               this to MAX_NAME_BUFF_LEN but ensure that
  3591.               the supplied string uses no more than
  3592.               MAX_NAME_LEN of the buffer. If the actual
  3593.               name used is of no interest this can be
  3594.               set to zero,  so the buffer will not be
  3595.               modified. This allows use of a literal
  3596.               string, eg. AddObjec(hcsys, "box", 0...)
  3597.  
  3598. fNewVertTol   The tolerence setting for creating new
  3599.               verticies rather than reusing old ones.
  3600.  
  3601. hobj          If the object already exists within
  3602.               Geometry and you simply want to give it a
  3603.               name, the existing object handle can be
  3604.               supplied here.
  3605.  
  3606. Comments
  3607.  
  3608. This function does not have to be used in conjunction
  3609. with StartPrim and EndPrim. It simply calls Geometry's
  3610. AddObject function to start an empty object in the given
  3611. coordinate system. However by supplying a name, the
  3612. object gets added to the object list on the control panel
  3613. thereby allowing the entire object to be selected by
  3614. highlighting its name.
  3615.  
  3616.  
  3617.  
  3618.  
  3619. HanCoorSys AddCoorSys(HanCoorSys hcsysParent,
  3620.                        char *szName,
  3621.                        ushort usBuffSize,
  3622.                        HanCoorSys hcsys,
  3623.                        Mat &matToParent,
  3624.                        Mat &matFromParent,
  3625.                        ushort usType,
  3626.                        bool bAddView);
  3627.  
  3628. hcsysParent   Handle to the parent coordinate system.
  3629.  
  3630. szName        The name of the coor sys to appear in the
  3631.               list box. The actual name used is returned
  3632.               in this buffer as the name supplied might
  3633.               already be in use. If this is the case a
  3634.               number is added to the end of the name.
  3635.  
  3636. usBuffSize    Size of the szName buffer. To ensure that
  3637.               the modified name will fit you can set
  3638.               this to MAX_NAME_BUFF_LEN but ensure that
  3639.               the supplied string uses no more than
  3640.               MAX_NAME_LEN of the buffer. If the actual
  3641.               name used is of no interest this can be
  3642.               set to zero,  so the buffer will not be
  3643.               modified. This allows use of a literal
  3644.               string, eg. AddCoorSys(hcsys, "new", 0...)
  3645.  
  3646. hcsys         If the coor sys already exists within
  3647.               Geometry and you simply want to give it a
  3648.               name, the existing handle can be supplied
  3649.               here.
  3650.  
  3651. matToParent   Matrix describing the transformation from
  3652.               child to parent. In other words this
  3653.               matrix transforms a point in the child
  3654.               coordinate system to its corresponding
  3655.               position relative to the parent coordinate
  3656.               system.
  3657.  
  3658. matFromParent The inverse or opposite matrix to
  3659.               matToParent. NB. The maths library can
  3660.               easily generate the inverse of a matrix by
  3661.               preeceeding it with a minus sign (eg. -
  3662.               mat).
  3663.  
  3664. usType             This value indicates wether the
  3665.               coordinate system being defined is right
  3666.               handed or left handed. It should be either
  3667.               CT_RIGHTHAND or CT_LEFTHAND.
  3668.  
  3669. bAddView       If this is set to TRUE a new view window
  3670. will appear.
  3671.  
  3672. Comments
  3673.  
  3674. Creates a new coordinate system as a child hcsysParent.
  3675. Its name will appear in the coor sys list box. There are
  3676. many advantages of using a named coordinate system rather
  3677. than creating an unamed one using the Geometry API, for
  3678. instance, a named coordinate system can be used in the
  3679. surface type dialog to specify an orientation for a
  3680. texture.
  3681.  
  3682.  
  3683.  
  3684.  
  3685. bool DelObject(const char *szName);
  3686.  
  3687. szName        The name of the object to delete.
  3688.  
  3689. Comments
  3690.  
  3691. Deletes a named object from Geometry and removes its name
  3692. from the listbox. The function returns TRUE if
  3693. successfull.
  3694.  
  3695.  
  3696.  
  3697.  
  3698. bool DelCoorSys(const char *szName);
  3699.  
  3700. szName        The name of the coordinate system to
  3701.               delete.
  3702.  
  3703. Comments
  3704.  
  3705. Deletes a named coordinate system from Geometry and
  3706. removes its name from the listbox. The function returns
  3707. TRUE if successfull.
  3708.  
  3709.  
  3710.  
  3711.  
  3712. ushort GetSelectedObjects(char *szNames, ushort
  3713. usBuffSize);
  3714.  
  3715. szNames       List of object names.
  3716.  
  3717. usBuffSize    Size of the szNames buffer.
  3718.  
  3719. Comments
  3720.  
  3721. Returns the list of object names that are highlighted in
  3722. the object listbox. Each name is terminated with a null,
  3723. and the entire list is terminated with a double null.
  3724.  
  3725.  
  3726.  
  3727.  
  3728. HanObject GetObjectHandle(const char *szName);
  3729.  
  3730. szName         The name of the object whose handle is to
  3731. be returned.
  3732.  
  3733. Comments
  3734.  
  3735. Returns the handle of the named object. A NULL_HANDLE is
  3736. returned if the name was not recognised.
  3737.  
  3738.  
  3739.  
  3740.  
  3741. HanObject GetCoorSysHandle(const char *szName);
  3742.  
  3743. szName         The name of the coor sys whose handle is
  3744. to be returned.
  3745.  
  3746. Comments
  3747.  
  3748. Returns the handle of the named coordinate system. A
  3749. NULL_HANDLE is returned if the name was not recognised.
  3750.  
  3751.  
  3752.  
  3753.  
  3754. void GetObjectName(HanObject hobj, char *szName,
  3755.                    ushort usBuffSize);
  3756.  
  3757. hobj          The handle of the object whose name we
  3758.               want returned.
  3759.  
  3760. szName        The name of the object.
  3761.  
  3762. usBuffSize    Length of the szName buffer.
  3763.  
  3764. Comments
  3765.  
  3766. Returns the name of a given object. A zero length string
  3767. is returned if the handle was not recognised.
  3768.  
  3769.  
  3770.  
  3771.  
  3772. void GetCoorSysName(HanCoorSys hcsys, char *szName,
  3773.                     ushort usBuffSize);
  3774.  
  3775. hcsys         The handle of the coor sys whose name we
  3776.               want returned.
  3777.  
  3778. szName        The name of the coor sys.
  3779.  
  3780. usBuffSize    Length of the szName buffer.
  3781.  
  3782. Comments
  3783.  
  3784. Returns the name of a given coor sys. A zero length
  3785. string is returned if the handle was not recognised.
  3786.  
  3787.  
  3788.  
  3789.  
  3790. void ForceRedraw(Redraw rd,
  3791.                 HanCoorSys hcsys=NULL_HANDLE);
  3792.  
  3793. rd            The redraw code to use.
  3794.  
  3795. hcsys         The handle of the coordinate system whose
  3796.               view is to be redrawn. If more than one
  3797.               view window exists for this coor sys they
  3798.               are all redrawn. If a NULL_HANDLE is
  3799.               passed, every view into the scene (ie. all
  3800.               coordinate systems) is redrawn.
  3801.  
  3802. Comments
  3803.  
  3804. Forces a redraw of one or more views. This function is
  3805. usefull if a tool constructs a dialog box which has
  3806. buttons that can be invoked independently of any events
  3807. from the editor. For instance the coor sys editing tool
  3808. has a dialog whose buttons could invoke a redraw. All
  3809. resulting DrawSoFar calls will be made before this call
  3810. returns.
  3811.  
  3812.  
  3813.  
  3814.  
  3815. void DrawMarker(HDC hdc, int iX, int iY, ushort usType);
  3816.  
  3817. hdc            Handle to device context to draw into.
  3818.  
  3819. iX             Device context X coordinate for marker.
  3820.  
  3821. iY             Device context Y Coordinate for marker.
  3822.  
  3823. usType              Type of marker to draw. Can be one of
  3824. the following values;
  3825.  
  3826.                MT_BOX         A small square marker
  3827.                MT_PLUS        A `+' shaped marker
  3828.                MT_CROSS       An `X' type cross marker
  3829.                MT_DIAMOND          A small diamond shaped
  3830. marker
  3831.  
  3832. Comments
  3833.  
  3834. Draws a marker into the device context at the specified
  3835. position using the current attribute (pen, colour, mode
  3836. etc) settings of the DC.
  3837.  
  3838.  
  3839.  
  3840.  
  3841. void DrawArrow(HDC hdc, int iX, int iY, ushort usFlags);
  3842.  
  3843. hdc           Device context to draw into.
  3844.  
  3845. iX            Device context x coordinate of the arrow
  3846.               head.
  3847.  
  3848. iY            Device context y coordinate of the arrow
  3849.               head.
  3850.  
  3851. usFlags       Type of marker to draw. Can be one of the
  3852.               following values;
  3853.  
  3854.               DA_FILLED     The arrow head is filled in
  3855.               DA_FIXEDSIZE  The arrow head is fixed in
  3856.                              size as opposed to
  3857.                              proportional to the length
  3858.                              of the arrow body
  3859.  
  3860. Comments
  3861.  
  3862. Draws an arrow from the current position in the device
  3863. context to iX, iY.
  3864.  
  3865.  
  3866.  
  3867.  
  3868. bool ActivateCSysWin(HanCoorSys hcsys);
  3869.  
  3870. hcsys         Handle of coordinate system whose view is
  3871.               to be activated.
  3872.  
  3873. Comments
  3874.  
  3875. Activates the view window associated with a coordinate
  3876. system. This means bringing it on top of the other
  3877. windows and highlighting its title bar. An OnViewChange
  3878. event will be received before this call returns.
  3879.  
  3880.  
  3881.  
  3882.  
  3883. HanSurf GetCurrentSurf();
  3884.  
  3885. Comments
  3886.  
  3887. Returns the handle of the currently selected surface
  3888. type.
  3889.  
  3890.  
  3891.  
  3892.  
  3893. void ModifiedScene();
  3894.  
  3895. Comments
  3896.  
  3897. This routine must be called after any tool modifies the
  3898. scene in any way. Not only does it mark the tool as the
  3899. one which should perform an undo if the user requests it,
  3900. but also it marks the document as modified such that a
  3901. warning will be issued if an attempt is made to close the
  3902. editor without saving it first.
  3903.  
  3904.  
  3905.  
  3906.  
  3907. void SetViewData(void *pvData, ushort usSize);
  3908.  
  3909. pvData        Pointer to the view data.
  3910.  
  3911. usSize        Size of the view data.
  3912.  
  3913. Comments
  3914.  
  3915. Sets the view data for every view in trhe scene to the
  3916. contents of pvData.
  3917.  
  3918.  
  3919.  
  3920.  
  3921. void BackgroundYield(const char *szWrite=NULL);
  3922.  
  3923. szWrite       An optional string which is written to the
  3924.               status bar at the bottom of the screen.
  3925.  
  3926. Comments
  3927.  
  3928. If a tool has a lot of processing to perform which could
  3929. take several seconds, even minutes, then somewhere in its
  3930. processing loop it should call this function. This
  3931. prevents the entire system being `locked up' during the
  3932. processing. The optional string can be used to print a
  3933. message to status bar to say for instance; "25% done".
  3934. Notice how the CSG tools use this.
  3935.  
  3936.  
  3937.  
  3938.  
  3939. Quick start to writing tools
  3940.  
  3941. The following source file is provided as a templete to
  3942. work from when creating new tools. Remember you must
  3943. define a 16x15 pixel bitmap with an id of one in your
  3944. resource file, and you must export _CREATETOOL and
  3945. _DELETETOOL in the .def file (the functions are
  3946. implemented by the IMPLEMENT_OBJECT macro).
  3947.  
  3948. From then on simply uncomment any events you are
  3949. interested in trapping. The whole of the Geometry, tool
  3950. interface, maths and debug API's are available to you as
  3951. well as the windows API.
  3952.  
  3953. Finally put an entry in the Gened.ini file so the editor
  3954. knows of the existence of your tool.
  3955.  
  3956. /*-------------------------------------------------------
  3957. --------------------
  3958.                ExampleTool
  3959.                -----------
  3960.  
  3961.      Example tool class
  3962.  
  3963.      (C) Silicon Dream Ltd 1995
  3964.  
  3965.   -------------------------------------------------------
  3966. --------------------
  3967.  
  3968. Changes:                           Date:
  3969. * Created file                     08/02/95
  3970. */
  3971.  
  3972. #include <tool.h>
  3973.  
  3974. #include "resource.h"
  3975.  
  3976. // YOU DO: Change the class name below to describe your
  3977. tool and anywhere else
  3978. //      this class name is used in this file
  3979. class ExampleTool: public Tool
  3980.      {
  3981.      private:
  3982.           // YOU DO: Declare your private variables here.
  3983. eg.
  3984.           //  Vec        vecCursorPos;
  3985.           //      (Non C++ users: 'private' means those
  3986.           //       variables which have global scope from
  3987.           //       within the functions you define here)
  3988.  
  3989.           // YOU DO: Uncomment any functions to trap
  3990. events you're interested in
  3991.           //  void _cppdyn Initialise();               //
  3992. Called once when DLL loaded
  3993.           //  void _cppdyn OnConfigure();              //
  3994. Called to configure tool
  3995.           //  Redraw _cppdyn OnSelect(Vec &vec);       //
  3996. Called when tool is selected
  3997.           //  Redraw _cppdyn OnUnSelect(bool
  3998. *pbOkToChange);     // Called when another tool is
  3999. selected
  4000.           //  Redraw _cppdyn OnButtonDown(Vec &vec);
  4001. // Called when button pressed
  4002.           //  Redraw _cppdyn OnMouseMove(Vec &vec);
  4003. // Called when mouse moves with button down
  4004.           //  Redraw _cppdyn OnButtonUp(Vec &vec);
  4005. // Called when button is released
  4006.           //  Redraw _cppdyn OnSet(Vec &vec);          //
  4007. Called when the 'Set' button is clicked
  4008.           //  Redraw _cppdyn OnUndo();            //
  4009. Called when user wishes to undo effect of tool
  4010.           //  Redraw _cppdyn OnDo(Vec &vec);      //
  4011. Called to end use of tool
  4012.           //  void _cppdyn OnViewChange(HanCoorSys hcsys,
  4013. Vec &vec); // Called when active view changes
  4014.           //  void _cppdyn DrawSoFar(HDC hdc, HanCoorSys
  4015. hcsys, void *pvViewData, bool bInvalid); // Called to
  4016. draw object so far into the view
  4017.  
  4018.      public:
  4019.           _cppdyn ~ExampleTool() {};
  4020.      };
  4021.  
  4022. IMPLEMENT_OBJECT(ExampleTool)
  4023.  
  4024. // YOU DO: Uncomment and fill in any functions for events
  4025. you want to trap.
  4026. //      (Non C++ users: If you create any functions of
  4027. your own which need
  4028. //       to access your private variables (see above),
  4029. you must make the
  4030. //       funtion part of your class by declaring it along
  4031. with the other
  4032. //       functions (see above), and prefixing the
  4033. function name with
  4034. //       'classname::' in the implementation)
  4035.  
  4036. /*
  4037. void _cppdyn ExampleTool::Initialise()
  4038.      {
  4039.      }
  4040. */
  4041. /*
  4042. void _cppdyn ExampleTool::OnConfigure()
  4043.      {
  4044.      }
  4045. */
  4046. /*
  4047. Redraw _cppdyn ExampleTool::OnSelect(Vec &vec)
  4048.      {
  4049.      return REDRAW_NONE;
  4050.      }
  4051. */
  4052. /*
  4053. Redraw _cppdyn ExampleTool::OnUnSelect(bool
  4054. *pbOkToChange)
  4055.      {
  4056.      *pbOkToChange=TRUE;
  4057.      return REDRAW_NONE;
  4058.      }
  4059. */
  4060. /*
  4061. Redraw _cppdyn ExampleTool::OnButtonDown(Vec &vec)
  4062.      {
  4063.      return REDRAW_NONE;
  4064.      }
  4065. */
  4066. /*
  4067. Redraw _cppdyn ExampleTool::OnMouseMove(Vec &vec)
  4068.      {
  4069.      return REDRAW_NONE;
  4070.      }
  4071. */
  4072. /*
  4073. Redraw _cppdyn ExampleTool::OnButtonUp(Vec &vec)
  4074.      {
  4075.      return REDRAW_NONE;
  4076.      }
  4077. */
  4078. /*
  4079. Redraw _cppdyn ExampleTool::OnSet(Vec &vec)
  4080.      {
  4081.      return REDRAW_NONE;
  4082.      }
  4083. */
  4084. /*
  4085. Redraw _cppdyn ExampleTool::OnUndo()
  4086.      {
  4087.      return REDRAW_NONE;
  4088.      }
  4089. */
  4090. /*
  4091. Redraw _cppdyn ExampleTool::OnDo(Vec &vec)
  4092.      {
  4093.      return REDRAW_NONE;
  4094.      }
  4095. */
  4096. /*
  4097. void _cppdyn ExampleTool::OnViewChange(HanCoorSys hcsys,
  4098. Vec &vec)
  4099.      {
  4100.      }
  4101. */
  4102. /*
  4103. void _cppdyn ExampleTool::DrawSoFar(HDC hdc, HanCoorSys
  4104. hcsys, void *pvViewData, bool bInvalid)
  4105.      {
  4106.      }
  4107. */
  4108.  
  4109.  
  4110.  
  4111. Maths Library
  4112. The maths library is implemented in a single DLL
  4113. containing usefull functions and classes for manipulating
  4114. graphical related objects such as vectors and matricies.
  4115. Currently Geometry accepts parameters to its functions as
  4116. C++ classes so the C version of the library is not really
  4117. usefull for programming tools or applications. However
  4118. eventually a C version of the API will also be included.
  4119.  
  4120. This section is split into two, the first part describing
  4121. the C support, the second describing the C++ support.
  4122.  
  4123. To use the DLL functions and classes you must include
  4124. either the `maths.h' include file (not to be confused
  4125. with C's math.h), for C users, or `cppmaths.h' for C++
  4126. users. Both must then link to `maths.lib'.
  4127.  
  4128. The C++ class interface is built on top of the C maths
  4129. library and provides no additional functionality that is
  4130. not available in the C library, however the C++ version
  4131. allows programs to be written which manipulate vectors
  4132. and matricies using algebraic formula and are therefore
  4133. easier to read. For instance;
  4134.  
  4135.      VectorA=VectorB+VectorC;
  4136.  
  4137. is easier to understand than;
  4138.  
  4139.      MthAddVec(&VectorA, &VectorB, &VectorC);
  4140.  
  4141. For C Users
  4142.  
  4143. Not yet written
  4144.  
  4145. For C++ Users
  4146.  
  4147. The C++ support is probably best described in terms  of
  4148. the class definitions and examples of the operations
  4149. available on those classes, rather than a function by
  4150. function breakdown.
  4151.  
  4152. Four types of class are available;
  4153.  
  4154. Vec       Implements a three element floating point
  4155. cartesian coordinate (x, y and z).
  4156. Lvec          Implements a four element floating point
  4157.          cartesian coordinate (x, y, z and w). NB. Only
  4158.          an Lvec can be multiplied by a matrix as a
  4159.          matrix has four rows.
  4160. Polar          Implements a three element floating point
  4161. polar coordinate (theta, phi and rho).
  4162. Mat       Implements a 4x4 floating point matrix.
  4163.  
  4164.  
  4165.  
  4166. Vectors
  4167.  
  4168. A vector can be used to store the position of a point in
  4169. 3D space or alternitively a direction relative to another
  4170. point. The following operations are defined for vectors;
  4171.  
  4172.    Vec vec(x, y, z)         Initialise a vector up to
  4173.    three values
  4174.    Vec vecA(vecB)      Initialise a vector with another
  4175.    vector
  4176.    Vec vec(lvec)            Initialise a vector with a
  4177.    long vector (loses last component)
  4178.    ((Vec) lvec)             Convert a long vector to a
  4179.    vector (loses last component)
  4180.    Vec vec(pol)         Initialise a vector with a polar
  4181.                          vector (conversion performed)
  4182.    ((Vec) pol)              Convert a polar vector to a
  4183.    vector (conversion performed)
  4184.    vecA+vecB           Add two vectors
  4185.    vecA-vecB           Subtract a vector from another
  4186.    vec*f                    Multiply a vector by a
  4187.    scalar
  4188.    vec*mat             Multiply a vector by a matrix
  4189.    vec/f                    Divide a vector by a scalar
  4190.    vecA+=vecB               Add two vectors (overwrite
  4191.    original)
  4192.    vecA-=vecB               Subtract a vector from
  4193.    another (overwrite original)
  4194.    vec*=f                   Multiply a vector by a
  4195.    scalar (overwrite original)
  4196.    vec*=mat            Multiply a vector by a matrix
  4197.    (overwrite original)
  4198.    vec/=f                   Divide a vector by a scalar
  4199.    (overwrite original)
  4200.    -vec                Returns the vector inverted
  4201.    vecA==vecB               Are two vectors equal?
  4202.    vecA!=vecB               Are two vectors not equal?
  4203.    vec.Set(x, y, z)         Set a vector's components
  4204.    vec.X()                  Get x component
  4205.    vec.Y()                  Get y component
  4206.    vec.Z()                  Get z component
  4207.    vec.Len()           Get length of vector
  4208.    vecA.Dot(vecB)      Get dot product of two vectors
  4209.    vecA.Cross(vecB)         Get cross product of two
  4210.    vectors
  4211.    vec.AddrVec()        Gets address of Vector member
  4212.                          (WARNING: Use only to interface
  4213.                          to non C++ code)
  4214.  
  4215.  
  4216.  
  4217. Long Vectors
  4218.  
  4219. Long vectors are designed primarily to allow
  4220. multiplication by matricies. The following operations are
  4221. defined for long vectors;
  4222.  
  4223.    LVec lvec(x, y, z, w)    Initialise a long vector
  4224.    with up to four values
  4225.    LVec lvecA(lvecB)        Initialise a long vector
  4226.    with another long vector
  4227.    LVec lvec(vec)       Initialise a long vector with a
  4228.                          vector (last component becomes
  4229.                          1.0)
  4230.    ((LVec) vec)         Convert a long vector to a
  4231.                          vector (last component becomes
  4232.                          1.0)
  4233.    lvec*mat            Multiply a long vector with a
  4234.    matrix
  4235.    lvec*=mat           Multiply a long vector with a
  4236.    matrix (overwrite original)
  4237.    lvecA==lvecB        Are two long vectors equal?
  4238.    lvecA!=lvecB             Are two long vectors not
  4239.    equal?
  4240.    lvec.Set(x, y, z, w)          Set a long vector's
  4241.    components
  4242.    lvec.X()            Get x component
  4243.    lvec.Y()            Get y component
  4244.    lvec.Z()            Get z component
  4245.    lvec.W()            Get w component (homogeneous
  4246.    coordinate)
  4247.    lvec.AddrLVec()      Gets address of LongVec member
  4248.                          (WARNING: Use only to interface
  4249.                          to non C++ code)
  4250.  
  4251. Polar Vectors
  4252.  
  4253. The following operations are defined for polar vectors;
  4254.  
  4255.    Polar pol(t, p, r)       Initialise a polar with up
  4256.    to three values
  4257.    Polar polA(polB)         Initialise a polar with
  4258.    another polar
  4259.    Polar pol(vec)      Initialise a polar with a vector
  4260.    (conversion performed)
  4261.    ((Polar) vec)            Convert a vector to a polar
  4262.    (conversion performed)
  4263.    polA==polB               Are two polars equal?
  4264.    polA!=polB               Are two polars not equal?
  4265.    pol.Set(t, p, r)         Set a polar's components
  4266.    pol.Theta()              Get theta component
  4267.    pol.Phi()           Get phi component
  4268.    pol.Rho()           Get rho component
  4269.    pol.AddrVec()        Gets address of Vector member
  4270.                          (WARNING: Use only to interface
  4271.                          to non C++ code)
  4272.  
  4273.  
  4274.  
  4275. Matricies
  4276.  
  4277. The following operations are defined for matricies;
  4278.  
  4279.    
  4280.    Mat mat             Initialise a matrix with the
  4281.    identity matrix
  4282.    Mat matA(matB)      Initialise a matrix with another
  4283.    matrix
  4284.    Mat mat(XROT, a)     Initialise a matrix with a
  4285.                          rotation or scale value (or
  4286.                          leave it unset)
  4287.    Mat mat(TRANSL, vec)     Initialise a matrix with a
  4288.    translation value (or leave it unset)
  4289.    Mat mat(vecOrigin, vecZAxis, vecYDir)  Initialise a
  4290.                          matrix by defining a new origin,
  4291.                          a direction for the z axis, and
  4292.                          given these constraints, a
  4293.                          direction towards which the y
  4294.                          axis will point.
  4295.    matA*matB           Multiply two matricies
  4296.    matA*=matB               Multiply two matricies
  4297.    (overwrite original)
  4298.    matA==matB               Are two matricies equal?
  4299.    matA!=matB               Are two matricies not equal?
  4300.    -mat                 Compute inverse of matrix (ie.
  4301.                          when multiplied by this gives
  4302.                          identity)
  4303.    mat.Set(f1,..f16)        Sets elements of a matrix
  4304.    mat.MoveParent(vec) Moves coor sys defined by matrix
  4305.    relative to its parent
  4306.    mat.MoveChild(vec)  Moves coor sys defined by matrix
  4307.    relative to itself
  4308.    mat.ScaleParent(x, y, z)      Scale coor sys defined
  4309.    by matrix relative to its parent
  4310.    mat.ScaleChild(x, y, z)  Scale coor sys defined by
  4311.    matrix relative to its own origin
  4312.    mat.XRotParent(a)        Rotates coor sys defined by
  4313.    matrix about parents x axis
  4314.    mat.XRotChild(a)         Rotates coor sys defined by
  4315.    matrix about its own x axis
  4316.    mat.YRotParent(a)        Rotates coor sys defined by
  4317.    matrix about parents y axis
  4318.    mat.YRotChild(a)         Rotates coor sys defined by
  4319.    matrix about its own y axis
  4320.    mat.ZRotParent(a)        Rotates coor sys defined by
  4321.    matrix about parents z axis
  4322.    mat.ZRotChild(a)         Rotates coor sys defined by
  4323.    matrix about its own z axis
  4324.    mat.ReverseX()      Reverses direction of x axis of
  4325.    coor sys defined by matrix
  4326.    mat.ReverseY()      Reverses direction of y axis of
  4327.    coor sys defined by matrix
  4328.    mat.ReverseZ()      Reverses direction of z axis of
  4329.    coor sys defined by matrix
  4330.    mat.AddrMat()        Gets address of Matrix member
  4331.                          (WARNING: Use only to interface
  4332.                          to non C++ code)
  4333.  
  4334.  
  4335.  
  4336. Debug Library
  4337. The debug library is not really part of Genesis but is a
  4338. very helpful debuging aid wether you're writing tools,
  4339. geometry engines, applications, in fact any code what so
  4340. ever. It can be used in windows or non-windows programs,
  4341. DLLs, C, or C++. What is more it presents you with just
  4342. one set of memory management functions.
  4343.  
  4344. Wether you are writing a simple C program, windows code
  4345. or whatever you use debug's Malloc and Free functions
  4346. (note the capitals letters to distinguish from C's memory
  4347. functions). If using C++ you can use New and Delete
  4348. (again with capitals). When your application or DLL
  4349. terminates, a call to DebListMem will output to a file
  4350. showing any memory which has been left unfreed, the size
  4351. of the memory, the module and line it was allocated in
  4352. and wether it was allocated with Malloc or New.
  4353.  
  4354. If you're programming under windows the Malloc and New
  4355. functions are not limited to allocating 64K segments.
  4356.  
  4357. If writing C code simply include `debug.h' and C++ users
  4358. should include `cppdebug.h'. In both cases you should
  4359. define the _DEBUG macro, this can be done with /D _DEBUG
  4360. on the compile line. The program must then be linked to
  4361. debug.lib.
  4362.  
  4363. The DebOut function can be used exactly like printf but
  4364. will output to a file. Each line appearing in the debug
  4365. output file is timestamped to within the accuracy of the
  4366. system clock. What is more since the output is buffered
  4367. into a 64K buffer it has practically zero impact on the
  4368. performance of your application and so can be used to
  4369. time `speed critical' parts of your code. When the buffer
  4370. becomes full and the file has to be flushed to disk a
  4371. line appears in the file saying that a flush happened at
  4372. this point in case there is a discrepancy in the time
  4373. stamps.
  4374.  
  4375. The debug filename is set by the string passed on the
  4376. very first call to DebOut. This string should contain a
  4377. valid filename. Directly after the filename you can put a
  4378. `+' character to indicate that the data should also be
  4379. directed to an additional output stream. Under windows
  4380. the additonal output stream will be the debug window, in
  4381. a regular C program it will be the screen. Because many
  4382. DLL's could all be printing on the additional output
  4383. stream simultaneously the output can look confusing and
  4384. the timestamps wont neccessarily be continuous.
  4385.  
  4386. Here is an example run;
  4387.  
  4388.  
  4389.      DebOut("C:\app.deb+");             // Open debug
  4390. file
  4391.      DebOut("Debug file has been opened");
  4392.      DebOut("Variable fLength is %f", fLength);     //
  4393. Output floating point variable
  4394.      pvoid1=Malloc(20);            // Allocates 20 bytes
  4395.      pvoid2=Malloc(30);            // Allocates 30 bytes
  4396.      pobj=New Obj;                 // Allocate a C++
  4397. object called Obj
  4398.      DebOut(FLUSH);           // Forces the debug file to
  4399. be flushed to disk
  4400.      DebOut("More debug");
  4401.      DebListMem();                 // List all unfreed
  4402. memory to debug file
  4403.      DebOut("Closing file now");
  4404.      DebOut(STOP);                 // Flushes and closes
  4405. the debug file
  4406.      Free(pvoid1);                 // Free memory...
  4407.      Free(pvoid2);
  4408.      Delete(pobj);
  4409.  
  4410. The following output will be generated;
  4411.  
  4412.     0.000: Debug file has been opened
  4413.     0.000: Variable fLength is 5.75
  4414.     0.000: --------: (Flushed)
  4415.     0.030: More debug
  4416.     0.030: Allocated memory dump:
  4417.     0.033:   Size   |     File     | Line  |  Alloc type
  4418.     0.033: ---------+--------------+-------+-------------
  4419. -
  4420.     0.033:     20   |     app.c    |  128  |   Malloc
  4421.     0.033:     30   |     app.c    |  129  |   Malloc
  4422.     0.033:    106   |     app.c    |  130  |    New
  4423.     0.040: Closing file now
  4424.  
  4425.  
  4426. If your code is compiled without the _DEBUG macro defined
  4427. then the memory allocation will not store the debugging
  4428. information required by DebMemList. What is more the
  4429. DebOut routine will not be included as part of your
  4430. application and so calls to it should be enclosed in
  4431. #ifdef's to prevent linker errors, eg;
  4432.  
  4433.      #ifdef _DEBUG
  4434.      DebOut("A line of debug");
  4435.      #endif
  4436.  
  4437. Instances of debug library
  4438.  
  4439. If you are building a large application consisting of
  4440. many DLLs, and statically linked libraries, then it is
  4441. sometimes not clear how many instances of the debug
  4442. library you have. Basically whenever you use the linker
  4443. and pass it the debug library's name, then you get an
  4444. instance of the library. The upshot of this is that you
  4445. cannot open a debug file in your application and expect
  4446. one of your DLLs to write to the same file. Any DLLs your
  4447. application use we're linked seperately and therefore
  4448. have their own copy of the debug library. Therefore they
  4449. should open their own debug file on the first call to
  4450. DebOut. Statically linked libraries however are not
  4451. linked independently and are therefore considered part of
  4452. the application or DLL using it.
  4453.  
  4454. Writing a Geometry engine
  4455.  
  4456. Writing a Geometry engine is the simple process of
  4457. writing a DLL whose interface conforms to the Geometry
  4458. API specification and which maps those functions onto its
  4459. own or a third party rendering engine or a hardware based
  4460. interface.
  4461.  
  4462. Of course there may be many differences between the new
  4463. renderer and Genesis's Geometry engine. For instance the
  4464. renderer might not have the concept of a coordinate
  4465. system. However as long as it has the ability to move
  4466. objects independently of one another then a coordinate
  4467. system can be implemented in the DLL which hides the
  4468. inadequecies of the renderer. It might also be that the
  4469. renderer uses integer rather than floating point
  4470. coordinates. Again this is easy to remedy, you could
  4471. adopt the convention that floating point numbers in the
  4472. range 0 to 100 get scaled to integer numbers 0 to 100,000
  4473. meaning that floating point numbers with an effective
  4474. resolution of 0.001 are supported. As long as the
  4475. coordinates are converted back on any query function then
  4476. a Geometry application will not know the difference.
  4477.  
  4478.  
  4479. Errors
  4480.  
  4481. The geometry.h file includes all of the standard geometry
  4482. errors. If a particular error code is listed in the
  4483. Geometry API spec as being returned from a particular
  4484. function, for instance, DefPatch returns
  4485. GERR_NOT_ON_PLANE if its points do not lie on a plane,
  4486. then any Geometry engine must return the same error
  4487. should the condition occur. This is because some
  4488. applications may check for this specific return code and
  4489. if it returns a more general error, such as
  4490. GERR_INT_PROCESSING_ERROR then the behaviour of the
  4491. application might change. The mark of a good Geometry
  4492. engine is one whose applications work identically to the
  4493. default.
  4494.  
  4495. If an error occurs in the new engine which a standard
  4496. error does not describe adaquetely then you can use
  4497. GERR_INT_PROCESSING_ERROR (internal processing error) or
  4498. define your own code whose value must be
  4499. GERR_UNKNOWN_ERROR (defined in geometry.h) or greater.
  4500. Such errors can have their own descriptions implemented
  4501. in the engine's GetErrorText function.
  4502.  
  4503.  
  4504. Handles
  4505.  
  4506. All handles are defined as 32 bit unsigned integers. The
  4507. geometry engine can use this value to mean whatever is
  4508. most convenient. For instance the default Geometry stores
  4509. a pointer to the appropriate object in this value. It can
  4510. also be used as an index into an array, however, the
  4511. value 0 cannot be used as this is reserved for the
  4512. NULL_HANDLE, so any such arrays must be based at one.
  4513.  
  4514. Handles do not have to be validated according to the
  4515. spec. To perform proper validation on all handles at
  4516. every call could be time cosuming, so if it is not
  4517. quickly and easily achieved, then do not worry about
  4518. implementing it. The onus is on the application and tool
  4519. writers to get the handles right.
  4520.  
  4521.  
  4522. Unsupported features
  4523.  
  4524. If a Geometry engine does not support a particular
  4525. feature say, bumped mapped textures, it should still
  4526. accept DefSurfType calls defining bump mapped textures
  4527. without returning a bad error. When rendered, the texture
  4528. should just appear as a normal image mapped texture. What
  4529. is more if the surface is queried with QrySurfType it
  4530. should return a SurfType structure with the bump mapped
  4531. flag set, otherwise as a particular model is saved and
  4532. loaded into editors with different engines then the model
  4533. will change. If it is loaded then saved again by an
  4534. editor whose engine does not support bump mapping, and
  4535. then the resulting file is loaded into an engine that
  4536. does, the texture will have lost its `bumpy' quality.
  4537. Likewise engines not supporting `curved' patches must
  4538. still store the normal information.
  4539.  
  4540.  
  4541. Helper library
  4542.  
  4543. A library is provided which contains functions common to
  4544. any Geometry engine thereby preventing any duplication of
  4545. work on behalf of the programmer. The library includes;
  4546.  
  4547.      ·    Validating patches (checks all points lie on a plane
  4548.       etc.)
  4549. ·    Splitting patches into smaller (possibly concave)
  4550. patches
  4551. ·    Computing patch normals
  4552. ·    Computing normals for `autosmooth' patches
  4553. ·    Loading and saving scenes
  4554. ·    Loading bitmaps for textures
  4555. ·    Providing text descriptions of Geometry errors
  4556.  
  4557. If the Geometry engine is compiled with the _DEBUG macro
  4558. defined then we must link to the debug version of the
  4559. helper library genhelpd.lib. Otherwise we should link to
  4560. the release version genhelp.lib. Notice there is no
  4561. include file for the helper library, everything you need
  4562. is defined in geometry.h.
  4563.  
  4564.  
  4565. API's
  4566.  
  4567. Any Geometry engine has at its disposal the whole of the
  4568. maths, debug and helper APIs. It should not attempt to
  4569. use the tool interface as there is no concept of tools in
  4570. the Geometry engine. Tools are purely an invention of the
  4571. editor application and the editor application should by
  4572. no means be the only one that can use the Geometry API.
  4573.  
  4574.  
  4575. GeomErr RegisterError (GeomErr gerrIn,
  4576.                       char *szFNIn, ushort usLineIn);
  4577.  
  4578. gerrIn        Geometry error to register.
  4579.  
  4580. szFNIn        Filename of the module in which the error
  4581.               occurred
  4582.  
  4583. usLineIn      The line number within the module at which
  4584.               the error occurred.
  4585.  
  4586. Comments
  4587.  
  4588. Registers a Geometry error. If an error occurs somewhere
  4589. within the Geometry engine, wether it is the result of
  4590. the application passing in bad parameters (eg.
  4591. GERR_INVALID_HANDLE), or due to circumstances beyond the
  4592. apps control (eg. GERR_OUT_OF_MEMORY) then the error must
  4593. be passed back to the the app. It is quite likely that
  4594. the app will then call the GetErrorText function to see
  4595. what went wrong and possibly to report the error to the
  4596. user. If the Geometry engine registers the error with
  4597. this routine before returning the error code then it
  4598. gives the GetErrorText routine in the helper library the
  4599. ability to build a more helpfull error string indicating
  4600. where exactly the error occured.
  4601.  
  4602. The Gerr() macro defined in geometry.h calls the
  4603. RegisterError function without worrying about how to work
  4604. out the module name and line number.
  4605.  
  4606. The following example code shows the recommended way of
  4607. returning errors;
  4608.      
  4609.      if (pmem==NULL)
  4610.           return Gerr(GERR_OUT_OF_MEMORY);
  4611.  
  4612. If the app then passes the returned error to GetErrorText
  4613. which in turn invokes the helper library function
  4614. GetHlpErrorText, then the following text will be
  4615. returned;
  4616.  
  4617.      Out of memory. Error occurred at line 850 in module
  4618. geometry.cpp.
  4619.  
  4620. If we returned the error without invoking the macro;
  4621.  
  4622.      if (pmem==NULL)
  4623.           return GERR_OUT_OF_MEMORY;
  4624.  
  4625. then the following text will be returned from
  4626. GetErrorText;
  4627.  
  4628.      Out of memory.
  4629.  
  4630. Implementation specific errors with values above
  4631. GERR_UNKNOWN_ERROR can also be registered.
  4632.  
  4633.  
  4634.  
  4635.  
  4636. GeomErr GetHlpErrorText (GeomErr gerr,
  4637.                          char *szBuff, ushort
  4638. usBuffSize);
  4639.  
  4640. gerr          The error whose text is to be returned.
  4641.  
  4642. szBuff        Buffer to contain message.
  4643.  
  4644. usBuffSize    Size of the supplied buffer.
  4645.  
  4646. Comments
  4647.  
  4648. This function can be called from the Geometry engine's
  4649. GetErrorText function. It supplies standard text
  4650. descriptions for all of Geometry's errors. If an
  4651. implmentation specific error is used (one with a value
  4652. above GERR_UNKNOWN_ERROR) then the buffer will contain
  4653. the following;
  4654.  
  4655.          `An implementation specific error occurred.
  4656.          Error was reported at line 850 in module
  4657.          geometry.cpp. Implementation interprets error
  4658.          as:'
  4659.  
  4660. and GERR_UNKNOWN_ERROR will be returned. The GetErrorText
  4661. function can then append its own implementation defined
  4662. description of the error if there is space in the buffer.
  4663. strlen can be used to find the length of the returned
  4664. string. If the GetHlpErrorText function runs out of
  4665. buffer space then it copies as much of the error text as
  4666. possible and puts three period characters, `...' in the
  4667. end of the buffer and returns GERR_BUFFER_TOO_SMALL.
  4668.  
  4669.  
  4670.  
  4671.  
  4672. GeomErr ValidPatch (Vec *avec,
  4673.                    ushort usNumVecs, ushort usFlags);
  4674.  
  4675. avec          A list of points to be used for the
  4676.               verticies.
  4677.  
  4678. usNumVecs     Number of points in avec.
  4679.  
  4680. usFlags       Flags used to idicate the kind of validity
  4681.               checks to perform;
  4682.  
  4683.      VP_CHECK_THIN_SEGMENT   Checks that no `thin'
  4684.                          segments appear in the patch
  4685.                          outline. A thin segment is where
  4686.                          part of the outline doubles back
  4687.                          on itself at a 180 degree angle,
  4688.                          forming an infinitely thin line
  4689.                          rather than an area.
  4690.  
  4691.      VP_CHECK_ON_PLANE  Checks that all the points lie
  4692.                          on a plane or within a tolerence
  4693.                          of the plane surface. The
  4694.                          tolerence used is proportional
  4695.                          to the size of the patch and is
  4696.                          approximately 1/50th the
  4697.                          greatest distance across any two
  4698.                          points on the patch outline.
  4699.                          This really only applies to
  4700.                          patches with more 4 or more
  4701.                          verticies.
  4702.  
  4703. Comments
  4704.  
  4705. Two checks are performed regardless of the flag setting,
  4706. first that at least three points have been supplied, and
  4707. secondly that no consequective points are coincident, ie
  4708. are in exactly the same place.
  4709. One check which is isn't performed is wether any line
  4710. segments in the patch's outline cross over thereby making
  4711. the ordering clockwise in one part and anticlockwise in
  4712. the other. We also do not check for concave outlines as
  4713. to some renderers a concave patch might well be a valid
  4714. patch. To those that don't support concave patches the
  4715. split function can be called to chop it up into smaller
  4716. convex patches.
  4717.  
  4718. In general this routine should not be called from
  4719. DefPatch if the DP_DONT_VALIDATE flag is used in the call
  4720. to DefPatch. This is because this call can be time
  4721. consuming if many patches are being created, and if the
  4722. application programmer is confident that no invalidate
  4723. patches will be passed then DP_DONT_VALIDATE can speed
  4724. things up.
  4725.  
  4726.  
  4727.  
  4728.  
  4729. GeomErr ExtractVecs (HanObject hobj, ushort usType,
  4730.                     Handle *ahan, ushort usNum,
  4731.                     Vec **pavec);
  4732.  
  4733. hobj          Handle to object containing verticies.
  4734.  
  4735. usType        Are we extracting verticies or normals?
  4736.               Value can be EV_NORMS or EV_VERTS.
  4737.  
  4738. ahan          Array of handles to verticies or normals.
  4739.  
  4740. usNum         Number of handles in ahan array.
  4741.  
  4742. pavec         The address of a pointer to Vec. The
  4743.               pointer to the allocated memory holding
  4744.               the vectors is returned here.
  4745.  
  4746. Comments
  4747.  
  4748. This routine extracts the vectors from a list of
  4749. verticies or normals using QryVertex or QryNormal
  4750. respectively. A buffer is allocated to contain the
  4751. vectors. This buffer must be freed by the calling code
  4752. using the Free call.
  4753.  
  4754. This routine is usefull for extracting vertex positions
  4755. in order to pass to routines such as ValidPatch, Split
  4756. and CompNormal.
  4757.  
  4758.  
  4759.  
  4760.  
  4761. GeomErr CompNormal (Vec *avec, ushort usNumVecs,
  4762.                       ushort usFlags, Vec *pvecNorm);
  4763.  
  4764. avec          Set of points to use for patch.
  4765.  
  4766. usNumVecs     Number of points in avec.
  4767.  
  4768. usFlags       Flags to specify the significance of the
  4769.               normal;
  4770.  
  4771.    CN_DIRECTION_IMPORTANT  The normal will point to the
  4772.                        side from which the points proceed
  4773.                        in a clockwise direction. Also if
  4774.                        we set this flag we must try and
  4775.                        set the CONVEX flag (if we know
  4776.                        for sure that the outline is
  4777.                        convex) and the coordinate system
  4778.                        type flag (appropriate to the
  4779.                        coordinate system the points
  4780.                        belong to).
  4781.    
  4782.    CN_CONVEX          If we know for certain that the
  4783.                        outline is convex, then we should
  4784.                        set this flag as it can reduce the
  4785.                        amount of processing this routine
  4786.                        has to do. If
  4787.                        CN_DIRECTION_IMPORTANT is not set
  4788.                        then this is not important.
  4789.    
  4790.    CT_LEFTHAND        If we know that this patch belongs
  4791.                        to a lefthand coor sys then we
  4792.                        should set this flag as it can
  4793.                        reduce the amount of processing
  4794.                        this routine has to do. If
  4795.                        CN_DIRECTION_IMPORTANT is not set
  4796.                        then this is not important.
  4797.    
  4798.    CT_RIGHTHAND       If we know that this patch belongs
  4799.                        to a righthand coor sys then we
  4800.                        should set this flag as it can
  4801.                        reduce the amount of processing
  4802.                        this routine has to do. If
  4803.                        CN_DIRECTION_IMPORTANT is not set
  4804.                        then this is not important.
  4805.  
  4806. pvecNorm      A unit length normal vector is returned
  4807.               here.
  4808.  
  4809. Comments
  4810.  
  4811. Computes the normal of a set of points. No check is made
  4812. to see if the points lie on a plane (use ValidPatch for
  4813. this). If the CN_DIRECTION_IMPORTANT is set then a lot
  4814. more processing is needed to work out which side the
  4815. normal should be facing. This processing can be reduced
  4816. by specifying as many of the other parameters as
  4817. possible. Concave patches always need the full processing
  4818. if CN_DIRECTION_IMPORTANT is set.
  4819.  
  4820. If the patch outline contains some points very close
  4821. together then this routine is selective in deciding which
  4822. three points to use to generate the normal. This ensures
  4823. we get an accurate a value as possible as the accuracy of
  4824. this normal is crucial to the operation of some of the
  4825. editors tools.
  4826.  
  4827.  
  4828.  
  4829.  
  4830. GeomErr Split (Vec *avecMain, ushort usNumMainVecs,
  4831.               ushort usMaxPerPatch, ushort usFlags,
  4832.               ushort *pusNumSets, void **apvSets,
  4833.               ushort *ausNumInSets);
  4834.  
  4835. avecMain      Set of points to split up.
  4836.  
  4837. usNumMainVecs Number of points in avecMain.
  4838.  
  4839. usMaxPerPatch The maximum number verticies per patch
  4840.               that this Geometry engine will allow.
  4841.  
  4842. usFlags       Flags controlling the operation;
  4843.  
  4844.    SP_SUPPORT_CONCAVE  Indicates wetherr the Geometry
  4845.                         engine supports concave patch
  4846.                         outlines.
  4847.  
  4848.    SP_RETURN_INDEX     Rather than returning an array of
  4849.                         vector arrays in (*apvSets)
  4850.                         instead we return an array of
  4851.                         ushort arrays, where each ushort
  4852.                         is an index into the original set
  4853.                         of points passed in.
  4854.  
  4855. pusNumSets    The number of sets returned, ie. the
  4856.               number of smaller outlines the main
  4857.               outline was split into.
  4858.  
  4859. apvSets       A pointer to an array of size
  4860.               (*pusNumSets) containing pointers to
  4861.               either arrays of vectorsor arrays of
  4862.               ushorts (if SP_RETURN_INDEX was given).
  4863.               Each of these arrays describes a set of
  4864.               points. If SP_RETURN_INDEX was specified
  4865.               than a variable declared; ushort
  4866.               **aausIndex, should be passed to apvSets,
  4867.               otherwise the variable should be; Vec
  4868.               **aavec; All arrays are allocated by this
  4869.               routine.
  4870.  
  4871. ausNumInSet   An array of ushorts indicating the size of
  4872.               the individual set arrays. For example
  4873.               ausNumInSet[2] contains the size of the
  4874.               array pointed to by apvSet[2]. In other
  4875.               words set 2 consists of elements
  4876.               apvSet[2][0] to
  4877.               apvSet[2][ausNumIntSet[2]].
  4878.  
  4879. Comments
  4880.  
  4881. This routine splits up an outline defined by a set of
  4882. points into a number of sets. The sets can be expressed
  4883. themselves as points or as indexes into the original
  4884. array avecMain. The sets are allocated by this routine,
  4885. but it is the responsibility of the calling code to Free
  4886. the memory when it has finished with it.
  4887.  
  4888. The following code fragment will free up all memory;
  4889.  
  4890.                for (us=usNumSets; us--;)
  4891.                     Free(aausIndex[us]);     // Free all
  4892. sets
  4893.                Free(aausIndex);              // Free
  4894. array of pointers to sets
  4895.                Free(ausNumInSet);       // Free array of
  4896. sizes of sets
  4897.  
  4898. Although we can pass in any number for usMaxPerPatch, in
  4899. practice the sets produced will not contain more than 4
  4900. points each, although these can be concave if
  4901. SP_SUPPORT_CONCAVE is set.
  4902.  
  4903.  
  4904.  
  4905.  
  4906. GeomErr Autosmooth (HanObject hobj, HanVertex *ahver,
  4907.                     ushort usNumVerts, Vec &vecNorm,
  4908.                     ushort usFlags, HanSurf hsur,
  4909.                     float fSmoothAng, HanNormal *ahnor,
  4910.                     ASUndoBuff *pasub);
  4911.  
  4912. hobj          Handle to object to add `autosmoothed'
  4913.               patch too.
  4914.  
  4915. ahver         Array of vertex handles defining the
  4916.               patch.
  4917.  
  4918. usNumVerts    Number of handles in ahver. Also specifies
  4919.               the size of the ahnor buffer.
  4920.  
  4921. vecNorm       The normal of the patch to be
  4922.               `autosmoothed'. The normal should point to
  4923.               the empty side of the patch.
  4924.  
  4925. usFlags       Flags controlling the operation;
  4926.  
  4927.    DP_SMOOTH_BY_SURFThis patch is to be smoothed only
  4928.                      with neighbouring patches which have
  4929.                      the same surface type.
  4930.  
  4931.    DP_SMOOTH_BY_ANGLE    This patch is to be smoothed
  4932.                      only with neighbouring patches which
  4933.                      form an angle less than fSmoothAng
  4934.                      with this patch.
  4935.  
  4936. hsur          Surface type of the `autosmoothed' patch.
  4937.  
  4938. fSmoothAng    Specifies autosmooth angle threshold if
  4939.               DP_SMOOTH_BY_ANGLE is set.
  4940.  
  4941. ahnor         An array of handles to normals returned.
  4942.  
  4943. pasub         Pointer to an autosmooth undo buffer. If
  4944.               the geometry engine wishes to abort this
  4945.               operation it can pass this to the UndoAS
  4946.               routine to undo any changes made. If not
  4947.               it must pass it to the ComitAS.
  4948.  
  4949. Comments
  4950.  
  4951. Given an array of vertex handles defining a new patch,
  4952. this routine can determine the set of normals to use to
  4953. get this patch to appear smooth given the criteria
  4954. defined in usFlags. It does this by looking at the
  4955. surrounding patches and averaging out the surface normals
  4956. of the patches to create the normals. If normals already
  4957. exist at these points they are modified, otherwise new
  4958. ones are created. The set of normals to use in defining
  4959. the patch is passed back in the ahnor parameter. The
  4960. returned pointer pasub should be passed either to UndoAS
  4961. or to CommitAS if the patch creation succeeded.
  4962.  
  4963.  
  4964.  
  4965.  
  4966. GeomErr CommitAS (ASUndoBuff *pasub);
  4967.  
  4968. pasub         Pointer to the autosmooth undo buffer.
  4969.  
  4970. Comments
  4971.  
  4972. Commits the changes made to the normals by the Autosmooth
  4973. function. Either this or UndoAS must be called at some
  4974. point after an Autosmooth call.
  4975.  
  4976.  
  4977.  
  4978.  
  4979. GeomErr UndoAS (ASUndoBuff *pasub);
  4980.  
  4981. pasub         Pointer to the autosmooth undo buffer.
  4982.  
  4983. Comments
  4984.  
  4985. Undoes the changes made to the normals by the Autosmooth
  4986. function. Either this or CommitAS must be called at some
  4987. point after an Autosmooth call.
  4988.  
  4989.  
  4990.  
  4991.  
  4992. GeomErr LoadBmp (char *szFN,
  4993.                   BITMAPINFO huge **ppbmi);
  4994.  
  4995. szFN          The name of a .bmp file to open.
  4996.  
  4997. ppbmi         The address of a pointer to a bitmap which
  4998.               will be returned after the bitmap is
  4999.               loaded. The memory is allocated by this
  5000.               routine.
  5001.  
  5002. Comments
  5003.  
  5004. Loads the bitmap with the specified name. The correct
  5005. amount of memory is automatically allocated and a pointer
  5006. to it is returned in (*ppbmi). The calling code must free
  5007. the memory using the Free call. If the bitmap does not
  5008. exist then GERR_BITMAP_FILE_NOT_FOUND is returned. If the
  5009. file has an incorrect format GERR_NOT_A_BMP_FILE is
  5010. returned.
  5011.  
  5012.  
  5013.  
  5014.  
  5015. GeomErr SaveSceneHlp (HFILE hfile, HanCoorSys hcsys,
  5016.                       ulong *pulNumCSys,
  5017.                       HanCoorSys *ahcsys,
  5018.                       ulong *pulNumObjs,
  5019.                       HanObject *ahobj);
  5020. hfile         Windows handle of the file to save too.
  5021.  
  5022. hcsys         Handle of the coordinate system to save.
  5023.  
  5024. pulNumCSys    Size of ahcsys (in number of handles). On
  5025.               return holds the total number of
  5026.               coordinate systems saved.
  5027.  
  5028. ahcsys        An array of handles to coordinate systems
  5029.               saved.
  5030.  
  5031. pulNumObjs    Size of ahobj (in number of handles). On
  5032.               return holds the total number of objects
  5033.               saved.
  5034.  
  5035. ahobj         An array of handles to objects saved.
  5036.  
  5037. Comments
  5038.  
  5039. This function takes exectly the same parameters as
  5040. Geometry's SaveScene function, so the implementation of
  5041. this routine is nothing more than calling this helper
  5042. routine.
  5043.  
  5044.  
  5045.  
  5046.  
  5047. GeomErr LoadSceneHlp (HFILE hfile, HanCoorSys csysParent,
  5048.                       Char *szTexPath,
  5049.                       ulong *pulNumCSys,
  5050.                       HanCoorSys *ahcsys,
  5051.                       ulong *pulNumObjs,
  5052.                       HanObject *ahobj);
  5053.  
  5054. hfile         Windows handle of the file to load from.
  5055.  
  5056. hcsysParent   Handle of the coordinate system which will
  5057.               be the parent of the one being loaded.
  5058.  
  5059. szTexPath     A pointer to a path specification for
  5060.               where to search for texture bitmaps if
  5061.               they are not found in the current working
  5062.               directory. This would typically be set to
  5063.               the directory where the model file is, or
  5064.               else a special texture directory. It must
  5065.               have terminating back slash eg;
  5066.               "c:\textures\" or else be a null string.
  5067.               The pointer cannot be NULL.
  5068.  
  5069. pulNumCSys    Size of ahcsys (in number of handles). On
  5070.               return holds the total number of
  5071.               coordinate systems loaded.
  5072.  
  5073. ahcsys        An array of handles to coordinate systems
  5074.               loaded.
  5075.  
  5076. pulNumObjs    Size of ahobj (in number of handles). On
  5077.               return holds the total number of objects
  5078.               loaded.
  5079.  
  5080. ahobj         An array of handles to objects loaded.
  5081.  
  5082. Comments
  5083.  
  5084. This function takes exectly the same parameters as
  5085. Geometry's LoadScene function, so the implementation of
  5086. this routine is nothing more than calling this helper
  5087. routine.
  5088.